接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。
一、抽象类
- 一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑,这样的类称为抽象类。如Animal对象,动物的集合,但是具体长什么样子我们不知道,是一个具体动物概念,所以是一个抽象类。
- 抽象类体现数据抽象的思想,是实现多态的一种机制。
- 特点:
- 抽象类不能被实例化,实例化的工作应该由它的子类来完成;
- 抽象方法必须由子类重写;
- 只有包含一个抽象方法的类,就必须定义为抽象类;
- 抽象类中可以包含具体的方法,也可以不包含抽象方法。
- 子类中的抽象方法不能与父类抽象方法同名。
- Abstract 不能与final同时修饰一个类;
- Abstract 不能与private,static,final,或native并列修饰同一个方法。
- 创建抽象类和抽象方法可以使类的抽象性明确起来,并告诉用户和编译器怎么打算使用它们,抽象类还是有用的重构器,可以容易的使公共方法沿着继承层次结构向上移动。
二、 接口
- 接口是一种比抽象类更加抽象的”类“。接口本身不是类,不能实例化一个接口。如new Runnable肯定是错误的;
- 实现接口的实现类必须实现接口所有的方法,标识遵循某个后某组特定的接口,同时表示interface只是它外貌,现在需要声明它是如何工作的。
- 接口是抽象类的延伸,弥补了Java不能多继承的权限,推荐接口和实现同时使用,保证数据安全性的同时实现多重继承。
- 接口是构建松耦合软件系统的重要法宝,由接口描述系统对外提供的所有服务。
- 特点:
- Interface 所有方法的访问权限默认为(而且必须为)public;
- 接口中可以定义常量,自动权限为:public static final
- 接口中不存在实现的方法。
- 实现接口的非抽象类必须实现接口所有的方法,抽象类可以不用实现。
- 不能使用new 操作符实例化一个接口,但是可以声明一个接口变量,该变量引用(refer to)一个实现该接口的类对象,可以使用instance of 检查一个对象是否实现了某个特定的接口,例如:if(an object instance of Comparable){}
- 在实现多接口的同时避免方法名重复。
- 接口的使用:
- 实现接口时,必须把方法声明为public,否则,编译器将认为这个方法的访问属性是包可见性,即类的默认访问权限。
- 接口可以被继承,extends
- 与接口相关的设计模式:
- 定制服务模式 :设计精粒度的接口,每个Java接口代表相关的一组服务,通过继承来创建复合接口
- 适配器模式 :当每个系统之间接口不匹配时,用适配器来转换接口
- 默认适配器模式:为接口提供简单的默认实现
- 代理模式:为Java接口的实现类创建代理类,使用者通过代理来获得实现类的服务
- 标识类型模式:用接口来标识一种没有任何行为的抽象类型
- 常量接口模式:在接口中定义静态常量,在其它类中通过import static语句引入这些常量
三、抽象类与接口
- 语法层次:
- 抽象类可以拥有任意范围的成员数据,和非抽象方法,接口只能有静态的,不能修改的成员数据,同时所有方法必须是抽象的,
- 对类而言,只能继承一个抽象类,但可以实现多个接口;
- 设计层次
- 抽象层次不同:抽象类是对类整体抽象,二接口是对(局部)行为抽象;
- 跨域不同:抽象类是从子类中发现公共部分,然后泛化为抽象类,子类继承该抽象类。体现的是一种继承关系,要想继承关系合理,父类和派生类必须存在"is-a"关系,而接口则不然,不要求接口和实现者在概念本质上一致,仅仅体现了接口定义的契约。
- 设计层次:抽象类而言是从下而上设计而来,先知道子类然后抽象出父类;接口不同,只需要定义一个规则,是自顶向下设计出来的。
四。 接口设计原则:ISP(Interface Segregation Principle):
- 面向对象的一个核心原则。它表明使用多个专门的接口比使用单一的总接口要好。
- 一个类对另外一个类的依赖性应当是建立在最小的接口上的。
- 一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染
其他接口相关:
五、对象克隆(implements )
- 默认的克隆操作是浅拷贝没有克隆包含在对象中的内部对象。
- 对于每一个类,需要做以下判断:
- 默认的clone方法是否满足要求,是否不应该使用clone
-
使用:
实现Cloneable接口
使用public 访问修饰符重新定义clone方法
- 即使是使用默认的浅拷贝可以满足要求,也应该实现Cloneable接口,然后重定义为public
六、 接口与回调
- 回调是一种常见设计模式,可以指出某个特定的事件发生时应该采取的动作。是通过接口来实现的,当然也可以通过类来实现,这就需要通过手动管理接口通知队列。
七、 内部类(定义在另一个类中的类)
- 使用内部类的三种:
- 内部类可以访问该类定义所在的作用域的数据,包括私有数据;
- 内部类可以对同一个包中的其他类隐藏起来;
- 当想要定义一个回调函数又不想编写大量代码时,可以使用匿名内部类。
- Java的内部类对象有一个隐式引用,引用了实例化该对象的外围对象。通过这个指针,可以访问外围类对象的全部状态。
OuterClass.this表示外围类对象引用
- 内部类是一种编译器现象,与虚拟机无关。编译器会把内部类翻译成$分割外部类名和内部类名的常规文件。
- 局部内部类:
- 好处:不能使用public private 访问符进行声明,对外部世界可以完全隐藏;
- 不仅可以访问包含他们的外部类,还可以访问局部变量,不过这些局部变量要声明为final;
public void start(final boolean beep){
Class TimerPrinter implements ActionListener{
public void actionPerformed(){
Date …
If(beep){
}
}
}
ActionListener listener = new TimerPrinter();
Timer t = new Timer();
t.start();
}
- 匿名内部类:有时只需要创建一个接口对象,就不需要命名了,只需要创建一个匿名内部类;
- 静态内部类:
- 使用内部类只是为了把一个类隐藏在另一个类的内部,并不需要外部类的用用,可以把内部类声明为static,以便小区产生的引用;
- 在内部类不需要访问外围类的时候,应使用匿名内部类,
- 声明在接口中的内部类自动为public static
接口和内部类
最新推荐文章于 2022-12-19 14:30:42 发布