面向对象之继承03(继承的限制)

继承的限制
利用extends关键字在大部分情况下不用考虑继承限制(前提:按照标准格式开发)。为了限制用户的使用,所以针对于继承也有一些自己的要求
1.java不允许多重继承,允许多层继承
c++允许多继承,即:允许一个类可以继承多个父类,类似的语法
错误的示例

class A{}
class B{}
class C extends A,B{}

这里是希望C类可以继承A和B两个类,但是以上的操作是不正确的。可以使用多层继承

class A{}
class B extends A{}
class C extends B{}

相当于C是B的子类,C是A的孙子类。在使用多层继承时,建议不超过三层继承关系
2.子类在继承父类时,会继承父类的全部操作,但是对于所有的私有操作是隐式继承,而所有非私有操作属于显式继承

class A{
    private String msg;
    public void setMsg(String msg){
        this.msg = msg;
    }
    public String getMsg(){
        return this.msg;
    }
}

class B extends A{
    public String print(){
        return this.msg;
    }

}

public class testDemo{
    public static void main(String args[]){
        B b = new B();
        b.setMsg("hello");
        System.out.println(b.getMsg());
        System.out.println(b.print());
    }
}

B类没有权限访问A类的私有属性
3.在子类对象构造之前,一定会默认调用父类的构造(默认使用无参数构造),以保证父类的对象先实例化,然后再实例化子类对象

class A{
    public A(){
        System.out.println("A、A类对象");
    }
}
class B extends A{
    public B(){
        System.out.println("B、B类对象");
    }
}

public class testDemo{
    public static void main(String args[]){
        new B();
    }
}

此时没有加入任何的操作代码,但是可以发现,在实例化子类对象时,先实例化了父类对象并调用了父类的无参构造方法
那么此时对于子类构造而言,就相当于隐含了一个"supper()"

class B extends A{
    public B(){
                supper();父类中有无构造加与不加无区别
        System.out.println("B、B类对象");
    }
}

如果父类中没有无参构造方法,那么就必须使用supper()明确调用父类的有参构造方法
错误示例

class A{
    public A(String title){
        System.out.println("A、A类对象");
    }
}
class B extends A{
    public B(){
        System.out.println("B、B类对象");
    }
}

public class testDemo{
    public static void main(String args[]){
        new B();
    }
}

编译报错

root@079a25844567:/opt/lixinghua/OOP# javac testDemo.java 
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
testDemo.java:7: error: constructor A in class A cannot be applied to given types; // 类A构造函数A未被应用规定的类型
    public B(){
              ^
  required: String
  found: no arguments
  reason: actual and formal argument lists differ in length // 原因:参数列表在长度上与实际格式不符
1 error

正确示例

class A{
    public A(String title){
        System.out.println("A、A类对象");
    }
}
class B extends A{
    public B(String title){
        super(title);
        System.out.println("B、B类对象");
    }
}

public class testDemo{
    public static void main(String args[]){
        new B("hello");
    }
}

以上证明 "super()"是让子类调用父类的构造方法,那么一定要放在子类构造方法的首行。这一点和"this()"是类似的
疑问?既然super()和this()都放在首行,如果子类构造没有编写super()则会自动调用父类的一个无参构造方法,如果写上this(),是不是子类无法调用构造方法了
验证表明:super()与this()不能同时出现,不管子类怎么折腾,它都只有一个存在的前提:子类对象的构造函数调用前一定要调用父类构造,为父类的对象初始化后才轮到子类初始化

猜你喜欢

转载自www.cnblogs.com/anyux/p/11897405.html
今日推荐