看了这篇,我确定你已经彻底搞懂Java的继承了
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了看了这篇,我确定你已经彻底搞懂Java的继承了,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5288字,纯文字阅读大概需要8分钟。
内容图文
![看了这篇,我确定你已经彻底搞懂Java的继承了](/upload/InfoBanner/zyjiaocheng/624/b54594f8a53a4fb4b865db79d3f0faf3.jpg)
遇到认真的读者是作者的一种幸运,真的,上一篇接口推送后,有好几个读者留言说,“二哥,你有一处内容需要修正,应该是接口中不能有 private 和 protected 修饰的方法。”说实话,看到这样的留言,我内心是非常欣慰的,因为你投出去的一块石头在水面上激起了一串美丽的涟漪。
在 Java 中,一个类可以继承另外一个类或者实现多个接口,我想这一点,大部分的读者应该都知道了。还有一点,我不确定大家是否知道,就是一个接口也可以继承另外一个接口,就像下面这样:
public?interface?OneInterface?extends?Cloneable?{
}
这样做有什么好处呢?我想有一部分读者应该已经猜出来了,就是实现了 OneInterface 接口的类,也可以使用 Object.clone()
方法了。
public?class?TestInterface?implements?OneInterface?{
????public?static?void?main(String[]?args)?throws?CloneNotSupportedException?{
????????TestInterface?c1?=?new?TestInterface();
????????TestInterface?c2?=?(TestInterface)?c1.clone();
????}
}
除此之外,我们还可以在 OneInterface 接口中定义其他一些抽象方法(比如说深拷贝),使该接口拥有 Cloneable 所不具有的功能。
public?interface?OneInterface?extends?Cloneable?{
????void?deepClone();
}
看到了吧?这就是继承的好处:子接口拥有了父接口的方法,使得子接口具有了父接口相同的行为;同时,子接口还可以在此基础上自由发挥,添加属于自己的行为。
以上,把“接口”换成“类”,结论同样成立。让我们来定义一个普通的父类 Wanger:
public?class?Wanger?{
????int?age;
????String?name;
????void?write()?{
????????System.out.println("我写了本《基督山伯爵》");
????}
}
然后,我们再来定义一个子类 Wangxiaoer,使用关键字 extends
来继承父类 Wanger:
public?class?Wangxiaoer?extends?Wanger{
????@Override
????void?write()?{
????????System.out.println("我写了本《茶花女》");
????}
}
我们可以将通用的方法和成员变量放在父类中,达到代码复用的目的;然后将特殊的方法和成员变量放在子类中,除此之外,子类还可以覆盖父类的方法(比如write()
方法)。这样,子类也就焕发出了新的生命力。
Java 只支持单一继承,这一点,我在上一篇接口的文章中已经提到过了。如果一个类在定义的时候没有使用 extends
关键字,那么它隐式地继承了 java.lang.Object
类——在我看来,这恐怕就是 Java 号称万物皆对象的真正原因了。
那究竟子类继承了父类的什么呢?
子类可以继承父类的非 private 成员变量,为了验证这一点,我们来看下面这个示例。
public?class?Wanger?{
????String?defaultName;
????private?String?privateName;
????public?String?publicName;
????protected?String?protectedName;
}
父类 Wanger 定义了四种类型的成员变量,缺省的 defaultName、私有的 privateName、共有的 publicName、受保护的 protectedName。
在子类 Wangxiaoer 中定义一个测试方法 testVariable()
:
可以确认,除了私有的 privateName,其他三种类型的成员变量都可以继承到。
同理,子类可以继承父类的非 private 方法,为了验证这一点,我们来看下面这个示例。
public?class?Wanger?{
????void?write()?{
????}
????private?void?privateWrite()?{
????}
????public?void?publicWrite()?{
????}
????protected?void?protectedWrite()?{
????}
}
父类 Wanger 定义了四种类型的方法,缺省的 write、私有的 privateWrite()、共有的 publicWrite()、受保护的 protectedWrite()。
在子类 Wangxiaoer 中定义一个 main 方法,并使用 new 关键字新建一个子类对象:
可以确认,除了私有的 privateWrite(),其他三种类型的方法都可以继承到。
不过,子类无法继承父类的构造方法。如果父类的构造方法是带有参数的,代码如下所示:
public?class?Wanger?{
????int?age;
????String?name;
????public?Wanger(int?age,?String?name)?{
????????this.age?=?age;
????????this.name?=?name;
????}
}
则必须在子类的构造器中显式地通过 super 关键字进行调用,否则编译器将提示以下错误:
修复后的代码如下所示:
public?class?Wangxiaoer?extends?Wanger{
????public?Wangxiaoer(int?age,?String?name)?{
????????super(age,?name);
????}
}
is-a 是继承的一个明显特征,就是说子类的对象引用类型可以是一个父类类型。
public?class?Wangxiaoer?extends?Wanger{
????public?static?void?main(String[]?args)?{
????????Wanger?wangxiaoer?=?new?Wangxiaoer();
????}
}
同理,子接口的实现类的对象引用类型也可以是一个父接口类型。
public?interface?OneInterface?extends?Cloneable?{
}
public?class?TestInterface?implements?OneInterface?{
????public?static?void?main(String[]?args)?{
????????Cloneable?c1?=?new?TestInterface();
????}
}
尽管一个类只能继承一个类,但一个类却可以实现多个接口,这一点,我在上一篇文章也提到过了。另外,还有一点我也提到了,就是 Java 8 之后,接口中可以定义 default 方法,这很方便,但也带来了新的问题:
如果一个类实现了多个接口,而这些接口中定义了相同签名的 default 方法,那么这个类就要重写该方法,否则编译无法通过。
FlyInterface 是一个会飞的接口,里面有一个签名为 sleep()
的默认方法:
public?interface?FlyInterface?{
????void?fly();
????default?void?sleep()?{
????????System.out.println("睡着飞");
????}
}
RunInterface 是一个会跑的接口,里面也有一个签名为 sleep()
的默认方法:
public?interface?RunInterface?{
????void?run();
????default?void?sleep()?{
????????System.out.println("睡着跑");
????}
}
Pig 类实现了 FlyInterface 和 RunInterface 两个接口,但这时候编译出错了。
原本,default 方法就是为实现该接口而不覆盖该方法的类提供默认实现的,现在,相同方法签名的 sleep()
方法把编译器搞懵逼了,只能重写了。
public?class?Pig?implements?FlyInterface,?RunInterface?{
????@Override
????public?void?fly()?{
????????System.out.println("会飞的猪");
????}
????@Override
????public?void?sleep()?{
????????System.out.println("只能重写了");
????}
????@Override
????public?void?run()?{
????????System.out.println("会跑的猪");
????}
}
类虽然不能继承多个类,但接口却可以继承多个接口,这一点,我不知道有没有触及到一些读者的知识盲区。
public?interface?WalkInterface?extends?FlyInterface,RunInterface{
????void?walk();
}
学到了吧?学到就是赚到。
https://github.com/itwanger/JavaBooks
内容总结
以上是互联网集市为您收集整理的看了这篇,我确定你已经彻底搞懂Java的继承了全部内容,希望文章能够帮你解决看了这篇,我确定你已经彻底搞懂Java的继承了所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。