联博_看了这篇,我确定你已经彻底搞懂Java的继续了
发表时间:2020-12-29 浏览量:8
看了这篇,我确定你已经彻底搞懂Java的继续了
遇到认真的读者是作者的一种幸运,真的,上一篇接口推送后,有好几个读者留言说,“二哥,你有一处内容需要修正,应该是接口中不能有 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 关键字新建一个子类工具:
,,www.u-healer.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。
可以确认,除了私有的 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
0
珍藏