18.设计辅助概念
1.final关键字
使用final定义类、属性、方法
final被称为终结器:
利用final定义的类不能有子类,方法不能被覆写,变量变为常量不能被修改。
如果在开发中定义了public static final定义的就是全局常量[常量使用大写字母]
2.对象多态性
开发中都要求继承抽象类和接口
多态性想要实现由两个前提:继承、覆写。
Java中多态性主要有两个方面组成:
-方法的多态性:
1.方法的重载
2.方法的覆写
-对象的多态性:父类与子类对象间的转换操作。
1.对象的向上转型:父类 父类对象 = 子类实例 自动完成
2.对象的向下转型:子类 子类对象 = (子类)父类实例 强制转换
class A{
public void print(){
System.out.println("A-hello");
}
}
class B extends A{
public void print(){
System.out.println("B-hello");
}
}
public class Test{
public static void main(String args[]){
A a=new B();//向上转型
B b=(B)a;//向下转型
a.print();//还是B-hello
b.print();//还是B-hello
}
}
分析向上转型的意义:
使用父类接受参数可以避免方法的大量重载。所以最大的意义在于数据操作的统一。
[例如一个方法要处理所有A类及其子类]
instanceof 关键字来判断类型
总结:
基本都是向上,向下很少用,不转型也还行。
19.抽象类
1.抽象类的基本概念
不会抽象类与接口,Java=没学
如果要定义一个没有方法体的方法,那么可以利用abstract关键字来进行抽象方法定义,而包含有抽象方法的类就可以用abstract来定义成为抽象类。
抽象类是不能够直接进行实例化操作的。
abstract class A{
abstract public void print();
}
class B extends A{
public void print(){
System.out.println("B-hello");
}
}
public class Test{
public static void main(String args[]){
new B().print();
}
}
抽象类必须有子类
抽象类的子类(如果不是抽象类),必须要覆写抽象类中的全部抽象方法
抽象类可以利用对象的向上转型机制,通过子类对象进行实例化操作。
抽象类与普通类最大的好处就是强制定义了子类的实现要求。也就给子类定了一个基本的格式。
大部分情况都是继承抽象类
2.抽象类相关说明
1.抽象类不能用final关键字来定义。
2.抽象类就是比普通类多了抽象方法而已。但是普通类中的所有结构抽象类都可以定义。
3.即便抽象类中没有抽象方法也无法直接对其进行实例化。
4.外部抽象类不允许使用static声明,内部抽象类可以使用static声明。
3.模板设计模式
当某一事物要实现特定功能必须按照父类提供的模板编写代码。
20.接口
接口与抽象类相比,接口的使用几率是最高的。
1.接口的定义
接口是一种特殊的类,但是在接口里面的组成与类不同,由抽象方法和全局常量来组成。
接口使用interface关键字来定义。
interface A{//定义了一个接口
public static final String MSG="Hello";
public abstract void print();
}
public class Test{
public static void main(String args[]){
new B().print();
}
}
接口的使用:
接口一定要定义子类,子类用implements关键字来实现接口,一个子类可以同时实现多个接口
[没有抽象类的单继承局限]
接口的子类如果不是抽象类,那么必须覆写接口中的全部抽象方法。
接口的对象利用子类对象的向上转型进行实例化操作。
interface A{//定义了一个接口
public static final String MSG="Hello";
public abstract void print();
}
interface B{
public abstract void fun();
}
class X implements A,B{//A同时实现AB两个接口
public void print(){
System.out.println("Aprint");
}
public void fun(){
System.out.println(MSG);
}
}
public class Test{
public static void main(String args[]){
X x=new X();
x.print();
x.fun();
}
}
注意:
就算接口定义中没有用public 也不是defult 而是public 接口是可以简化定义的。
抽象类可以用各种权限而接口只有public
一般定义接口的时候省略abstract 和 public static final
当程序中出现,类、抽象类、接口的时候,如果普通类既要继承抽象类又要继承接口则
calss 子类 extends 抽象类 implements 接口{}
总结与抽象类区别
1.抽象类可以用各种权限,接口public
2.子类可以实现多个接口,而只能单继承抽象类
抽象类可以直接实现接口,这时候抽象方法会包括接口中的抽象方法
反过来,接口不能继承抽象类,但是一个接口可以使用extends继承多个父接口,叫做接口多继承
总结接口使用
接口避免了单继承局限。
接口都是抽象方法,很少定义全局常量
所有的内部类结构都不受到语法的限制。
实际使用原则
1.制定操作标准
2.表示一种能力
3.将服务器端的远程方法视图提供给客户端
2.使用接口定义标准
现实生活中对接口不陌生,例如USB。
U盘和键盘通过USB接口来和电脑联系,电脑通过USB来找设备的请求。
不管什么设备只要一链接到USB上就要执行固定的一系列操作。
interface USB{//定义了一个USB标准
public void start();
public void stop();
}
class Computer{//电脑
public void plugin(USB usb){//电脑接受从USB插入的设备
usb.start();
usb.stop();
}
}
class Flash implements USB{//根据USB标准来定义U盘的操作
public void start(){
System.out.println("flash working!");
}
public void stop(){
System.out.println("flash stop!");
}
}
class Keyboard implements USB{//根据USB标准来定义U盘的操作
public void start(){
System.out.println("KB working");
}
public void stop(){
System.out.println("KB stop!");
}
}
public class Test{
public static void main(String args[]){
Computer computer=new Computer();
computer.plugin(new Flash());
computer.plugin(new Keyboard());
}
}
这样的子类是按照严格的操作标准使用着,而在调用处也很简单。不论你是调用U盘还是键盘,只要是USB设备我对你的操作都是一样的模式。
即便有几千万个子类也是可以通过一个接口来使用的。
说的高级一点:接口可以连接两个不同的层。
[图20.2]
3.工厂设计模式-接口的应用(Factory)
如果要扩充程序却影响了客户端的执行这样的设计就非常糟糕。
可参考Java可移植性的实现原理:
不可移植:程序→操作系统
可移植:程序→JVM→操作系统 可以在客户端与接口之间引入中间层。
例如
interface Fruit{//水果
public void eat();
}
class Apple implements Fruit{//苹果
public void eat(){
System.out.println("eat apple!");
}
}
class Cherry implements Fruit{//樱桃
public void eat(){
System.out.println("eat cherry!");
}
}
class Factory{//
//当程序需要扩充更多的水果类
//我也只需要修改这里的工厂类
public static Fruit getInstance(String classname){//直接取得接口实例
if("Apple".equals(classname)){
return new Apple();
}
else if ("Cherry".equals(classname)){
return new Cherry();
}
else
return null;
}
}
public class Test{
public static void main(String args[]){//为了方便模拟调用
Fruit f=Factory.getInstance(args[0]);
if(f!=null)
f.eat();
}
//命令行输入
//java Test Apple
//java Test Cherry
}
直接修改工厂类即可实现增加子类而不需要去修改客户端
4.代理设计模式-接口的应用(Proxy)
所谓的代理结构指的是在接口上的一种应用,一个接口有一个核心的操作主题,但是只依靠这个核心主题无法完成所需要的功能,那么需要一个代理主题,代理完成有关的功能。
interface Subject{//核心操作主题
public void get();//核心操作
}
class RealSubject implements Subject{//真实主题
public void get(){
System.out.println("dean 讨债成功");
}
}
class ProxySubject implements Subject{//代理真实主题
private Subject subject;//
public ProxySubject(Subject subject){//讲真正要干的传进来
this.subject=subject;
}
public void prepare(){
System.out.println("准备!");
}
public void destroy(){
System.out.println("结束!");
}
public void get(){
this.prepare();//准备工作
this.subject.get();//真实主题的实现
this.destroy();
}
}
public class Test{
public static void main(String args[]){
Subject sub = new ProxySubject(new RealSubject());
sub.get();
}
}
5.抽象类与接口的区别
目前为止:抽象类,类,对象,接口,这些概念从开发上来讲什么关系呢?
接口用来指定标准,抽象类和类都是标准的一个实现,而抽象类是对象的过渡层。
所有类的抽象使用的就是接口。
N0. | 区别 | 抽象类 | 接口 |
1 | 定义关键字 | abstract class | interface |
2 | 组成 | 属性、常量、抽象方法、方法 | 抽象方法+全局常量 |
3 | 权限 | 各种权限 | 只能够public |
4 | 子类实现 | extends继承一个 | implement实现多个接口 |
5 | 关系 | 可以实现多个接口 | 不能继承抽象类但可以接口多继承 |
6 | 实例化 | 依靠子类对象的向上转型实现抽象类或者接口的实例化 | |
7 | 设计模式 | 模板设计模式 | 工厂、代理设计模式 |
8 | 操作局限 | 单继承局限 | 没有单继承局限 |
通过对比可以发现,抽象类和接口都可以实现对子类的限制,优先考虑接口。