参考:
https://www.liaoxuefeng.com/wiki/1252599548343744/1260454548196032
例子
Person类:
class Person {
private String name;
private int age;
public String getName() {...}
public void setName(String name) {...}
public int getAge() {...}
public void setAge(int age) {...}
}
Student类:
class Student {
private String name;
private int age;
private int score;
public String getName() {...}
public void setName(String name) {...}
public int getAge() {...}
public void setAge(int age) {...}
public int getScore() { … }
public void setScore(int score) { … }
}
对比之后,Student类比Person类多了字段score、getScore()、setScore()
不想再多coding,怎么办???继承
当我们让Student从Person继承时,Student就获得了Person的所有功能,我们只需要为Student编写新增的功能。
使用extends关键字来实现继承:
class Person {
private String name;
private int age;
public String getName() {...}
public void setName(String name) {...}
public int getAge() {...}
public void setAge(int age) {...}
}
class Student extends Person {
// 不要重复name和age字段/方法,
// 只需要定义新增score字段/方法:
private int score;
public int getScore() { … }
public void setScore(int score) { … }
}
注意:子类自动获得了父类的所有字段,严禁定义与父类重名的字段!
一个问题
子类无法访问父类的private字段或者private方法。例如,Student类就无法访问Person类的name和age字段:
class Person {
private String name;
private int age;
}
class Student extends Person {
public String hello() {
return "Hello, " + name; // 编译错误:无法访问name字段
}
}
为了让子类可以访问父类的字段,我们需要把private改为protected。用protected修饰的字段可以被子类访问:
class Person {
protected String name;
protected int age;
}
class Student extends Person {
public String hello() {
return "Hello, " + name; // OK!
}
}
任何class的构造方法,第一行语句必须是调用父类的构造方法。如果没有明确地调用父类的构造方法,编译器会帮我们自动加一句super(); 如果父类没有默认的构造方法,子类就必须显式调用super()并给出参数以便让编译器定位到父类的一个合适的构造方法。即子类不会继承任何父类的构造方法。子类默认的构造方法是编译器自动生成的,不是继承的。
super(name, age); // 显式调用父类的构造方法Person(String, int)
向上转型
ok的
Student s = new Student();
Person p = s; // upcasting, ok,student变为person
Object o1 = p; // upcasting, ok,person变为object
Object o2 = s; // upcasting, ok,student变为object
向下转型
向下转型很可能失败,不能把父类变为子类,因为子类功能比父类多,多的功能无法凭空变出来。
了避免向下转型出错,Java提供了instanceof操作符,判断一个变量所指向的实例是否是指定类型,或者这个类型的子类。如果一个引用变量为null,那么对任何instanceof的判断都为false。
区分继承和组合
class Student extends Person {
protected Book book;
protected int score;
}
Student持有一个Book实例