一.接口
接口出现的目的:
1.体现封装性;
2.分离契约和实现;
3.区分甲方(提要求)和乙方(干活);
接口可以认为就是一份合同(契约)。
语法定义:
interface 接口名称 {
void volumnUp(); 抽象方法
}
//容器
interface Collection{
interface DataStructure{}
}
interface List extends Collection,DataStructure{
}
1.接口的定义允许多继承;
2.接口无法去实例化对象;
3.接口中给出的方法列表默认:
(1)public访问限定符修饰
(2)无法使用static修饰(有特例)
(3)是一个抽象方法,直接用分号结尾,不用给出方法体
4.接口中不能出现属性,可以出现方法,认都是被 final static修饰;
interface JavaCourse {
void 上课();
void 辅导();
void 留作业();
}
类实现接口的语法,写在定义类的时候。
class 陈老师 implement JavaCourse {
@Override
void 上课(){…}
…
}
class 唐老师 implement JavaCourse {
@Override
void 上课(){…}
}
class A extends Parent implement IA,IB,IC {
}
final关键字修饰三个位置:
1.修饰变量,不可变变量,只有一次赋值机会
final int a = 10;
a = 100 // 触发编译错误
final int[] a = new int[10];
A) a = new int[100]; // 触发编译错误
B) a[0] = 100; // 正确
final Person p = new Person();
A) p = null; // 触发编译错误
B) p.name = “Hello”; // 正确
2.final 可以修饰类,表示这个类不能被继承
final class A{}
3.final可以修饰方法,表示这个方法无法被其他子类覆写
class A {
final void method(){}
}
二.abstract
1.修饰类,这个类无法被实例化
abstract class A {} 抽象类
new A(); // 编译错误
2.修饰方法,该方法称为抽象方法,只有方法签名,没有方法实现
abstract void method();
List(接口)
抽象方法:
pushFront/pushBack/insert
AbstractList(抽象类)实现了List
覆写了pushFront/pushBack
留了一个抽象方法 insert
LinkedList(类) 继承了abstractList 实现了List
ArrayList(类)继承了 AbstractList 实现了List覆写了 insert
1.抽象方法一旦被实现了一次,就不再是抽象方法
2.AbstractList中只是线性表,把公共代码提取出来复用,所以无法实现insert方法,因为顺序表和链表的insert是不同的
三.多态(继承和多态都是取自生物学的术语)
猫和狗都是动物,都可以叫,但是种类不同,叫声不同
1.父类型的引用可以指向子类型的对象
List
AbstractList
ArrayList LinkedList
List p = new ArrayList();
AbstractList q = new ArrayList();
ArrayList o = new ArrayList();
以返回值类型体现:
List getList(){
return ArrayList();
}
以参数体现:
void list(List list){…}
list(new ArrayList());
list(new LinkedList());
2.引用可以调用的方法有哪些,在编译期间是根据引用的类型决定的,不是根据对象的类型
class A {
int a(){}
}
class B extends A {
int b(){};
}
A aa = new A();
aa.a();
A ab = new B();
ab.a();
ab.b(); // 编译错误
B bb =new B();
bb.a();
bb.b();
B ba = new A(); // 编译错误
class Demo {
public static void main(String[] args) {
List list = OtherClass.getList();
list.方法();
}
}
3.运行期间,真正执行的是哪个方法?
普通方法
class A {
void method(){sout(“我是A”); //aa.method();
class B {
@Override
void method(){sout(“我是B”); //ab.method();
//bb.method();
abstract class Animal { abstract void bark();}
class Dog extends Animal {
@Override
void bark(){汪汪}
}
class Cat extends Animal {
@Override
void bark(){喵喵}
如果是静态方法呢?
class A {
static void method(){sout(“A”);}
}
class B {
static void method(){sout(“B”);}
}
A aa = new A();
aa.method(); // ==A.method();
a ab = new B();
ab.method() //==A.method();
B bb = new B();
bb.method(); //==B.method();
多态的语法总结:
1.父类型的引用可以指向子类型的对象(向上转型)
2.编译期间,可以调用的方法列表,以引用类型为准
3.运行期间,真正执行的普通方法,以实际执行的对象类型为准
4.运行期间,真正执行的静态方法,以应用类型为准
向下转型:
Object
List
AbstractList
ArrayList
A ab = new B();
ab.methodOfB(); // 编译错误
B bb = (B)ab;
如果ab实际上不是指向B类型的对象,不会有编译错误,但会触发运行时错误,为了避免类型转化错误,Java提供了一个运算符判断引用背后的真实对象类型(发生在运行期间)
instanceof
ab instanceof B;
ab引用指向的对象能否被B类型的引用指向