题记
今天在尝试看源码,但是发现好多abstract,虽然明白abstract是怎么用的,但是总觉得他和interface应用起来实际没太大区别。就在刚刚想明白了一些。
先拿ReentrantLock举例子
声明
public class ReentrantLock implements Lock, java.io.Serializable
内部类
abstract static class Sync extends AbstractQueuedSynchronizer
AQS
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable
可以看到源码中abstract用的很多
个人看法
我认为啊,abstract更多的就是为了限制你,让你选择正确的上层,并且不能摇摆。而interface可以多元化的选择。
先上一下文字定义
1.相同点
A. 两者都是抽象类,都不能实例化。
B. interface实现类及abstrctclass的子类都必须要实现已经声明的抽象方法。
2. 不同点
A. interface需要实现,要用implements,而abstract class需要继承,要用extends。
B. 一个类可以实现多个interface,但一个类只能继承一个abstract class。
C. interface强调特定功能的实现,而abstractclass强调所属关系。
D. 尽管interface实现类及abstrct class的子类都必须要实现相应的抽象方法,但实现的形式不同。interface中的每一个方法都是抽象方法,都只是声明的(declaration,没有方法体),实现类必须要实现。而abstractclass的子类可以有选择地实现。
例子
比如我们想养只狗,不想养猫,那这时候我们定义一个抽象类的狗,继承狗就可以了。这样既可以保证狗的多态(泰迪、柯基、哈士奇),又能直观的知道这是狗,不是猫。我还想规定,作为狗你要是想跑,我给你提供一个你可以参考的跑的方法。
先做关于狗的限制
创建抽象的狗类
// 想限制的方法上也需要加abstract
public abstract class AbstractDog {
public abstract void eat();
}
创建哈士奇的类,继承狗类
public class HaShiQi extends AbstractDog{
public static void main(String[] args) {
HaShiQi haShiQi = new HaShiQi();
haShiQi.eat();
}
@Override
public void eat() {
System.out.println("哈士奇专属狗粮");
}
}
运行结果:哈士奇专属狗粮
增加实现
现在虽然限制了作为狗,吃只能吃狗粮,但是作为动物,他们都可以睡觉,作为宠物,他们都会有主人,所以这时候可以再定义两个接口类
创建动物的接口类
public interface Animal {
void sleep();
}
创建宠物的接口类
public interface Pet {
void master();
}
HaShiQi 实现 Animal 和 Pet 接口
public class HaShiQi extends AbstractDog implements Animal,Pet{
public static void main(String[] args) {
HaShiQi haShiQi = new HaShiQi();
haShiQi.eat();
haShiQi.sleep();
haShiQi.master();
}
@Override
public void eat() {
System.out.println("哈士奇专属狗粮");
}
@Override
public void sleep() {
System.out.println("二哈的睡觉姿势");
}
@Override
public void master() {
System.out.println("二哈的主人--" + Thread.currentThread().getName());
}
}
输出结果
哈士奇专属狗粮\
二哈的睡觉姿势\
二哈的主人--main
Process finished with exit code 0
狗类增加跑的方法
public abstract class AbstractDog {
public abstract void eat();
public void run(){
System.out.println("我可以时速800m");
}
}
main方法增加调用
public static void main(String[] args) {
HaShiQi haShiQi = new HaShiQi();
haShiQi.eat();
haShiQi.sleep();
haShiQi.master();
// 调用新加的run方法
haShiQi.run();
}
输出结果 哈士奇专属狗粮 二哈的睡觉姿势 二哈的主人--main 我可以时速800m
Process finished with exit code 0
感叹一下
做了这么多年业务开发,感觉是个老程序员了,回过头去再看看当时的基础性的东西,发现还差得远。本篇文章只是我个人的看法,如果有不正确欢迎指点。