Java解惑之理解继承的本质


Java解惑之理解继承的本质

继承不只是复制基类的接口,当创建了一个导出对象时,该对象包含了一个基类的子对象

“组合和继承都允许在新的类中放置子类对象,组合是显式的这样做,而继承则是隐式的做”。

介绍

《Think in Java》中有这样一句话:复用代码是 Java 众多引人注目的功能之一。但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情。

在这句话中最引人注目的是“复用代码”,尽可能的复用代码使我们程序员一直在追求的,现在我来介绍一种复用代码的方式,也是 Java 三大特性之一—继承。

什么时候需要继承?

描述对象关系 “is a”的时候
建议:慎用继承 !明确需要使用向上转型的时候再使用继承,否则考虑组合。

对比组合模式

描述对象关系 “is a”的时候

super关键字

子类的构造函数默认第一行会默认调用父类无参的构造函数,隐式语句(通过在程序编译阶段插入代码完成)

常见错误

public class Sub extends Super {
    
    public Sub(String s) {
        
    }
    
    public static void main(String[] args) {
        Sub sub = new Sub();
    }
}

class Super {
    String s;
    public Super(String s) {
        this.s = s;
    }
}

原因:由于用户为父类编写的构造函数,编译器就不提供默认的构造函数,而上文中提到:子类构造函数隐式调用父类无参数构造函数,所以会出现Implicit super constructor is undefined for default constructor. Must define an explicit constructor问题

**解决: **1:为父类添加默认的构造器

​ 2:删除子类的构造器

​ 3:在子类构造器中显示调用super(s)

protecte关键字的的内涵

  • 基类的protected成员是包内可见的,并且对(包内对象的)子类可见;(意思是说 通过包外的父类引用声明父类对象父类protected成员不可见)
  • 企图跨越不同的包,从子类中调用基类实例的受保护方法。明显不行。
  • 若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法

例子

clone介绍

clone 来自java.lang.Object

其声明如下:

protected native Object clone() throws CloneNotSupportedException;

1.同包访问不同包的方法

package com.an.protectedStudy;

/**
 * @Auther: bxan
 * @Date: 2018/12/28 22:48
 * @Description:
 */
class A{

}
public class TestOne {
    public static void main(String[] args) {
        A a = new A();
        a.clone(); //'clone()' has protected access in 'java.lang.Object'
    }
}

解释: protected 权限意味着只有子类和同包下的类可以访问该方法。com.an.protectedStudy 明显不同包TestOne也不是子类

public class Test7 {}
class MyObject extends Test7 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Test7 test = new Test7();
        test.clone(); // Compile error.
    }
}

package 1
class MyObject5 extends Test5 {}

package 2
public class Test5 {
    public static void main(String args[]) throws CloneNotSupportedException {
        MyObject5 obj = new MyObject5();
        obj.clone(); // Compile OK
    }
}

向上转型

Java permits an object of a subclass type to be treated as an object of any superclass type. This is called upcasting.

  • 允许子类类型被对待为父类类型
  • 本质:

First, you must understand, that by casting you are not actually changing the object itself, you are just labeling it differently.

通过转型仅仅是为对象贴上了不同的标签。

参考

《Thinking in Java》

http://wiki.jikexueyuan.com/project/java-enhancement/java-two.html

https://blog.csdn.net/justloveyou_/article/details/61672133

https://www.jianshu.com/p/b041e6876256?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

国外很赞的文章:

http://www.cs.utexas.edu/~cannata/cs345/Class%20Notes/14%20Java%20Upcasting%20Downcasting.htm


文章作者: Bxan
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Bxan !
  目录