一、接口
接口的出现解决java中单一继承的限制,使类可以实现多个接口
1.接口的特点:
接口是更纯粹的抽象类,特点如下:
1).成员变量:只能是常量(使用final修饰),不存在变量;
2).成员方法:成员方法只能是抽象函数(使用abstract修饰);
3).静态函数:不存在静态函数(原因:接口的方法都要由子类实现,静态函数不能被重写,或者说abstract和static不能共存)
4).构造函数:没有构造函数。(原因:都是常量,不需要构造函数来改变其值)
5).getter和setter方法:接口中没有函数体,不存在这两个方法。
调用成员常量:直接接口类名.常量名;
调用成员方法:在子类中实现调用。
2.格式:
interface ImA {
int AGE = 18;
String name = "Yao Ming";
void eat();
void sleep();
}
public class ClassA implements ImA {
@Override
public void eat() {
System.out.println(ImA.name+"吃饭");
}
@Override
public void sleep() {
System.out.println(ImA.AGE+"睡觉");
}
}
public class Main {
public static void main(String[] args) {
ClassA classA = new ClassA();
classA.eat();
}
}
上面格式方面由几个要注意的:
(1) 成员变量方面:全格式为 public abstract final int AGE = 18;
成员方法方面:全格式为 public abstract void eat();
省略写的话,系统会自动补齐;
(2) 子类实现接口,相当于重写接口方法。返回类型 函数名 参数都要一致
3.接口与类的关系:
1).类与类的关系:单一继承,多层继承
2).类与接口的关系:多个实现
3).接口与接口的关系:多继承,多层继承
4.接口的优点:
1)解决Java中单一继承的限制,提高代码扩展性。
2)降低耦合性(继承有很大的耦合性)
3)即用即插,不用即拔。使用方便
4)代表一种规范
5.应用:
二、多态:
1.描述:同一种事物的多种形态;
2.多态的前提:
1).继承关系(实现接口也是继承)
2).方法的重写
3).父类的引用指向子类对象
3.多态的判定方法:
设置这个判定规则的原因是使用多态的时候,一定要过编译和运行这两个关口。在父类的引用指向子类的对象时候,我们往往会想到底是调用父类的成员,还是子类的成员(如果是父类和子类有相同名称成员的时候)。以下就有这样的判断规则。
成员变量:编译时看左边(父类),运行时看左边(父类);
成员方法:编译时看左边(父类),运行时看右边(子类)
静态方法:编译时看左边(父类),运行时看左边(子类)
总结:编译都看左边,运行时,成员方法看右边。其他(成员变量,静态方法)看左边。
要保证编译和运行同时能过,才不会报错。
4.多态中的向上转型和向下转型
(和Java中的基本数据类型转换相似)
(和Java中的基本数据类型转换相似)
向上转型:把一个子类赋值给一个父类:(类似隐式转换)
向下转型:把一个父类强制转型为一个子类(类似显式转换)
向下转型:把一个父类强制转型为一个子类(类似显式转换)
5.从案例看多态:
案例1:利用多态的动态绑定方法,自动调用子类重写的方法;利用多态的向上转换和向下转换,调用子类的独有函数
/* 定义一个接口Animal,有成员方法 吃饭;
* 定义一个子类 Cat,有成员方法 吃饭 ,独有方法 玩;
* 定义一个Dog类,有成员方法 吃饭,有独特方法 看门
*
* 在测试类中体现多态*/
* 定义一个Dog类,有成员方法 吃饭,有独特方法 看门
*
* 在测试类中体现多态*/
interface Animal {
public abstract void eat();
}
public class Cat implements Animal{
@Override
public void eat() {
System.out.println("猫在吃饭");
}
public void play()
{
System.out.println("猫在玩球");
}
}
public class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗在啃骨头");
}
public void watchDoor()
{
System.out.println("狗在看门");
}
}
public static void main(String[] args) {
Animal a = new Cat();
method(new Dog());
method(new Cat());
}
//自动调用相应子类的独特方法
public static void method(Animal a)
{
if(a instanceof Dog)//判断数据属于某个引用数据类型
{
((Dog) a).watchDoor();
}
else if(a instanceof Cat) {
((Cat) a).play();
}
}
}
//