类到对象是实例化,对象到类是抽象
抽象类:
1.什么是抽象类?
类和类之间具有共同特征,将这些共同特征提取出来,形成抽象类。
类本身是不存在的,所以抽象类无法创建对象(无法实例化)。
2.抽象类属于什么类型?
抽象类也属于引用数据类型。
3.抽象类怎么定义?
【修饰符列表】 abstract class 类名{
类体;
}
4.抽象类是无法实例化的,无法创建对象的,所以抽象类是用来被子类继承的,子类继承抽象类,子类可以实例化对象。
5.final和abstract不能联合使用,这两个关键字是对立的。
6.抽象类的子类可以是抽象类
7.抽象类虽然无法实例化,但是抽象类有构造方法,这个构造方法是供子类使用的。
8.抽象类关联到一个概念:抽象方法,什么是抽象方法呢?
抽象方法表示没有实现的方法,没有方法体的方法。例如:
public abstract void doSome();
抽象方法的特点:
1.没有方法体,以分号结尾
2.前面修饰符列表中有abstract关键字。
9.抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中。
判断:java语言中凡是没有方法体的方法都是抽象方法?
不对
Object类中就有很多方法没有方法体,都是以“;"结尾的,但他们都不是抽象方法。
例如: public native int hashCode();
这个方法调用C++写的动态链接库程序。前面修饰符列表中没有:abstract,有一个native,表示调用JVM本地程序。
抽象类:
1.抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中。
2.重要结论:一个非抽象的类继承抽象类,必须将抽象类中的抽象方法实现了。这是java语法上强行规定的,必须的,不然编译器就报错了。
这里的覆盖或者说重写,也可以叫做实现。(对抽象的实现)
public class AbstractTest{
public static void main(String[] args){
//能不能使用多态?
//父类型引用指向子类型对象
Animal a = new Bird(); //向上转型。(自动类型转换)
//这就是面向抽象编程
//a的类型是Animal,Animal是抽象的
//面向抽象编程,不要面向具体编程,降低程序的耦合度,提高程序的扩展力
//这种面程符合OCP原则
/*分析以下:
编译的时候这个move()方法是谁的?
—编译的时候是Animal的
运行的时候这个move()方法是谁的?
—运行的时候是Bird的
a.move();
}
}
//动物类(抽象类)
abstract class Animal{
//抽象方法
public abstract void move();
}
//子类(非抽象类)
//错误:Bird不是抽象的,并且未覆盖Animal中的抽象方法move()
/*
class Bird extends Animal{
}
*/
//如果Bird是抽象类的话,那么这个Animal中继承过来的抽象方法也可以不去重写/覆盖/实现
abstract class Bird extends Animla{
}
class Bird extends Animal{
//需要将从父类中继承过来的抽象方法进行覆盖/重写,或者也可以叫做“实现”
//把抽象的方法实现了
public void move(){
}
}
/*
分析:
Animal是父类,并且是抽象类。Animal这个抽象类中有一个抽象方法move.
Bird是子类,并且是非抽象类。Bird继承Animal之后,会将抽象方法继承过来。
*/
接口:
1.接口也是一种“引用数据类型”,编译之后也是一个class字节码文件
2.接口是完全抽象的。(抽象类是半抽象)或者也可以说接口是特殊的抽象类。
3.接口怎么定义,语法是什么?
【修饰符列表】 interface 接口名{}
4.接口支持多继承,一个接口可以继承多个接口。
5.接口中只包含两部分内容,一部分是:常量。一部分是:抽象方法。接口中没有其他内容了,只有以上两部分。
6.接口中所有的元素都是public修饰的。(都是公开的)
7.接口中的抽象方法定义时:public abstract可以省略。
8.接口中的方法都是抽象方法,所以接口中的方法不能有方法体。
9.接口中的常量的public static final可以省略。
10.类和类之间叫做继承,类和接口之间叫做实现,仍然可以将“实现”看作"继承“。
继承使用extends关键字完成,实现使用implements关键字完成。
11.结论:当一个非抽象的类实现接口的话,必须将接口中所有的抽象方法全部实现(覆盖,重写)
接口和接口之间支持多继承,那么一个类可以同时实现多个接口吗?
对于计算机来说,一个机箱上有多个接口,一个接口是接键盘的,一个接口是接鼠标的,
一个接口是接电源的,一个接口是接显示器的……
重点:一个类可以同时实现多个接口。
这种机制弥补了java中的那个缺陷?
java中类和类只支持单继承,实际上单继承是为了简单而出现的,现实世界中存在多继承,java中的接口弥补了单继承带来的缺陷。
接口A和接口B虽然没有继承关系,但是写代码的时候,可以互转。编译器没意见。但是运行时可能出现:
ClassCastException异常。
之前的一个结论:
无论是向上转型还是向下转型,两种类型之间必须要有继承关系,没有继承关系编译器会报错。(这个不适用接口方面)
最终实际上和之前还是一样,需要加:instanceof运算符进行判断
向下转型养成好习惯。转型之前先if+instanceof进行判断
一个非抽象的类,实现接口的时候,必须将接口中所有方法加以实现。
接口中的方法不能有方法体。
继承和实现都存在的话,代码应该怎么写?
extends 关键字在前
implements 关键字在后
使用接口,写代码的时候,可以使用多态(父类型引用指向子类型对象)
接口在开发中的应用
注意:接口在开发中的作用,类似于多态在开发中的作用
多态:面向抽象编程,不要面向具体编程。降低程序的耦合度,提高程序的扩展力。
/*
public class Master{
public void feed(Dog d){ }
public void feed(Cat c){ }
//假设又要养其他动物,那么这个时候需要再加一个方法。(需要修改代码)
//这样扩展力太差了,违背了OCP原则(对扩展开放,对修改关闭)
}
}
*/
public class Master{
public void feed(Animal a){
//面向Animal父类编程,父类是比子类更抽象的。
//所以我们叫做面向抽象编程,不要面向具体编程。
//这样程序的扩展力就强
}
}
接口在开发中的作用?
接口是完全抽象的。
面向抽象编程可以修改为:面向接口编程
有了接口就有了可插拔。可插拔表示扩展力很强,不是写死的。
接口有什么用?
扩展性好,可插拔。
接口是一个抽象的概念
分析:中午去饭馆吃饭,这个过程中有接口吗?
接口是抽象的。
菜单是一个接口。(菜单上有一个抽象的照片)
谁面向接口调用。(顾客面向菜单点菜,调用接口。)
谁负责实现这个接口。(后台的厨师负责把菜做好,是接口的实现者。)
这个接口有什么用?
这个饭馆的“菜单”,让“顾客”和“后厨”解耦合了。
顾客不用找后厨了,后厨不用找顾客了。他们之间完全依靠这个抽象的菜单沟通。
面向接口编程,可以降低程序的耦合度,提高程序的扩展力。符合OCP开发原则。
接口的使用离不开多态机制。(接口+多态才可以达到降低耦合度。)
接口可以解耦合,解开的是谁和谁的耦合?
任何一个接口都有调用者和实现者。
接口可以将调用者和实现者解耦合。
调用者面向接口调用。
实现者面向接口编写实现。
以后进行大项目的开发,一般都是将项目分离成一个模块一个模块的。
模块和模块之间采用接口衔接。降低耦合度。
类型和类型之间的关系:
is a(继承) has a(关联) like a(实现)
is a :Cat is a Animal(猫是一个动物)
凡是能够满足is a的表示"继承关系"
A extends B
has a : I has a Pen(我有一支笔)
凡是能够满足has a关系的表示“关联关系"
关联关系通常以”属性“的形式存在
A{
B b;
}
like a:Cooker like a FoodMenu(厨师像一个菜单一样)
凡是能够满足like a关系的表示”实现关系")
实现关系通常是:类实现接口
A implements B
抽象类是半抽象的
接口是完全抽象的
抽象类中有构造方法
接口中没有构造方法
接口和接口之间支持多继承
类和类之间只能单继承
一个类可以同时实现多个接口
一个抽象类只能继承一个类(单继承)
接口中只允许出现常量和抽象方法
以后接口使用的比抽象类多,一般抽象类使用的比较少
接口一般都是对“行为”的抽象