继承的细节
-
子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访
问,要通过父类提供公共的方法去访问
-
创建子类对象时,会调用子类的无参构造器,同时也会调用父类的无参构造器
子类必须调用父类的构造器, 完成父类的初始化
//只取部分代码 复制以下代码运行会不成功
public class Base extends TopBase { //父类
public Base() { //无参构造器
System.out.println("父类 Base()构造器被调用....");
}
public Sub() {
//super() 不显示出来 但会默认调用
System.out.println("子类 sub()构造器被调用....");
}
public Text{
public static void main (String args[]){
Sub sub= new Sub();
}
}
//输出结果
//
//父类 Base()构造器被调用....
//子类 sub()构造器被调用....
// 子类必须调用父类的构造器, 完成父类的初始化
-
当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,
//只取部分代码 复制以下代码运行会不成功 public class Base extends TopBase { //父类 public Base() { //无参构造器 System.out.println("父类 Base()构造器被调用...."); } public Base(String name) { System.out.println("父类 Base(String name)构造器被调用...."); } public Sub() { //super() 不显示出来 但会默认调用 System.out.println("子类 sub()构造器被调用...."); } public class Sub extends Base{ //子类 public Sub(String name){ System.out.println("子类 Sub(String name)构造器被调用...."); } public class Text{ public static void main(String[] args) { Sub sub= new Sub("lihua"); } } } //输出结果 //System.out.println("父类 Base()构造器被调用...."); //System.out.println("子类 Sub(String name)构造器被调用....");
- 如果父类没有提供无 参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
//可运行
class Base { //父类
//无 无参构造器
public Base(String name) {
System.out.println("父类 Base(String name)构造器被调用....");
}
public Base(String name, int age) {
System.out.println("父类 Base(String name ,int age)构造器被调用....");
}
}
class Sub extends Base {
public Sub() {
//super() 不显示出来 但会默认调用
super("liming",18);
System.out.println("子类 sub()构造器被调用....");
}
public Sub(String name) {
super("liming",18);
// super("liming");
System.out.println("子类 Sub(String name)构造器被调用....");
}
public Sub(String name,int age) {
super("liming",18);
System.out.println("子类 Sub(String name,int age)构造器被调用....");
}
}
public class Text {
public static void main(String[] args) {
Sub sub1 = new Sub("lihua");
System.out.println();
Sub sub2 = new Sub("lihua",18);
}
}
//输出结果
父类 Base(String name ,int age)构造器被调用....
子类 Sub(String name)构造器被调用....
父类 Base(String name ,int age)构造器被调用....
子类 Sub(String name,int age)构造器被调用....
//果父类没有提供**无 参构造器**,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作
-
如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)
class Base { //父类 public Base() { System.out.println("父类 Base()构造器被调用...."); } public Base(String name) { System.out.println("父类 Base(String name)构造器被调用...."); } public Base(String name, int age) { System.out.println("父类 Base(String name ,int age)构造器被调用...."); } } class Sub extends Base { public Sub() { //super() 不显示出来 但会默认调用 super(); System.out.println("子类 sub()构造器被调用...."); } public Sub(String name) { super("liming"); // super("liming"); System.out.println("子类 Sub(String name)构造器被调用...."); } public Sub(String name,int age) { super("liming",18); System.out.println("子类 Sub(String name,int age)构造器被调用...."); } } public class Text { public static void main(String[] args) { Sub sub1 = new Sub(); System.out.println(); Sub sub2 = new Sub("lihua"); System.out.println(); Sub sub3 = new Sub("lihua",18); System.out.println(); } } //运行结果 父类 Base()构造器被调用.... 子类 sub()构造器被调用.... 父类 Base(String name)构造器被调用.... 子类 Sub(String name)构造器被调用.... 父类 Base(String name ,int age)构造器被调用.... 子类 Sub(String name,int age)构造器被调用.... //要调用 那个父类的某个构造器,就在父类构造器下 super(参数列表) //如 super("liming"); super("liming",18);
-
super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)
super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
//对的
public Sub(String name) {
super();
System.out.println("子类 Sub(String name)构造器被调用....");
}
//错的
public Sub(String name) {
System.out.println("子类 Sub(String name)构造器被调用....");
super();
}
-
java 所有类都是 Object 类的子类, Object 是所有类的基类
-
父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类)
//意思就是现有父亲再有儿子,子类构造器的初始化要先调用父类的构造器(初始化)
//每一个子类都有一个super();
-
子类最多只能继承一个父类(指直接继承),即 java是单继承机制。
-
不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系
//比如人类不能继承音乐类, //Penson extends Music 错的 //但是猫类可以继承动物类 //Cat extends Animal 对的 //谁是什么?要同 大类