封装
类的属性和方法的具体实现对外隐藏,只通过对外暴露的方法进行属性的设置和修改,不能直接操作类的属性进行更改。
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
- private修饰类的属性
- public方法对外暴露
继承
关键字extends
public class Parent {
public void hobby() {
System.out.println("喜欢看电视");
}
}
public class Son extends Parent{
public static void main(String[] args) {
Son son = new Son();
son.hobby(); // 喜欢看电视
}
}
子类可以继承父类已有的方法。
重写
public class Son extends Parent{
@Override
public void hobby() {
System.out.println("喜欢运动");
}
public static void main(String[] args) {
Son son = new Son();
son.hobby();// 喜欢运动
}
}
子类可以拥有与父类相同的方法并且@Override注解,运行时执行的时子类的方法。
重载
public class Son extends Parent {
@Override
public void hobby() {
System.out.println("喜欢运动");
}
public void hobby(String name) {
System.out.println(name + "喜欢运动");
}
public static void main(String[] args) {
Son son = new Son();
son.hobby(); // 喜欢运动
son.hobby("张三"); // 张三喜欢运动
}
}
同一个类中,可以有同样的方法名,但是返回值或者方法参数不一样,叫做方法的重载。而重写发生在继承关系的父子类中。
构造器
public class Parent {
public Parent() {
System.out.println("父类构造器!");
}
}
public class Son extends Parent {
public Son() {
System.out.println("子类构造器!");
}
public static void main(String[] args) {
Son son = new Son();
/**
* 输出顺序:
* 父类构造器!
* 子类构造器!
*/
}
}
子类在创建对象的时候,会先执行父类构造器,再执行子类构造器。
静态代码块
public class Parent {
static {
System.out.println("父类静态代码块");
}
public Parent() {
System.out.println("父类构造器!");
}
}
public class Son extends Parent {
static {
System.out.println("子类静态代码块");
}
public Son() {
System.out.println("子类构造器!");
}
public static void main(String[] args) {
Son son = new Son();
/**
* 输出顺序:
* 父类静态代码块
* 子类静态代码块
* 父类构造器!
* 子类构造器!
*/
}
}
抽象类
由abstract修饰的类叫做抽象类。
public abstract class Demo {
public abstract void method01();
public void method02(){
// doSomething
}
}
- 抽象类不一定要有抽象方法
- 抽象类中可以有普通方法
- 抽象类无法实例化
- 抽象类有构造函数
接口
interface 关键字修饰的类。
public interface Demo {
void method01();
}
- 定义规范,不能通过new实例化
- 没有构造函数
- 类中的所有方法都是抽象的
多态
前提:有类继承或者接口实现,子类要重写父类的方法。
向上转型 / 自动转型
public class Parent {
public void hobby() {
System.out.println("喜欢看电视");
}
}
public class Son extends Parent {
@Override
public void hobby() {
System.out.println("喜欢运动");
}
public static void main(String[] args) {
Parent parent = new Son();
parent.hobby(); // 喜欢运动
}
}
子类转换成父类,自动转型。
子类重写父类的方法,父类调用该方法执行的是子类的方法。
缺点是父类不能调用子类独有的方法,编译不通过。
向下转型 / 强转
public class Parent {
public void hobby() {
System.out.println("喜欢看电视");
}
}
public class Son extends Parent {
@Override
public void hobby() {
System.out.println("喜欢运动");
}
public static void main(String[] args) {
Parent parent = new Son();
parent.hobby();
}
}
public class Daughter extends Parent{
@Override
public void hobby() {
System.out.println("喜欢唱歌");
}
}
public static void main(String[] args) {
Parent parent = new Son();
Son son = (Son) parent;
Daughter daughter = (Daughter) parent; // ClassCastException异常
}
父类转换成子类对象,需要强制类型转换。
不同类继承同一个父类,强转可能不成功,发生类转换异常。所以向下转型一般要先instanceof判断是否是这个子类class。