一.接口
1.接口的定义和使用
接口名:和类名一样,首字母大写
public interface 接口名{//接口中的成员,一般写一些抽象方法
}
public class 类名 implements 接口名{//复写接口中所有的抽象方法
}
2.接口的成员热点:
(1)JDK7以及以前的版本
1)接口中可以定义变量,默认被 public static final 修饰 (也就是常量)
2)接口中只能是抽象方法,不能有其他方法。
(2)JDK8之后
3)允许在接口定义默认方法(用于接口升级,它的实现类不用重写),使用public default 修饰,是带方法体的方法。
4)允许在接口中定义静态方法,使用只能用接口名调用(其实现类的对象无法调用)
public class DemoSM {public static void main(String[] args) {SMImpl sm = new SMImpl();//sm.show();StaticMethod.show();}
}//定义实现类
class SMImpl implements StaticMethod {//如果两个实现两个接口,有相同的静态方法,无逻辑冲突问题//因为其静态方法只能用接口名调用
}interface StaticMethod {public static void show(){System.out.println("我是SM中的静态方法");}
}
(3)JDK9
5)允许在接口中定义私有方法(用于抽取默认方法相同的部分),用private修饰,只能用于本类,外类不能访问。
3.接口与类之间的关系
1)类与类的关系:单继承的关系
2)类与接口的关系:多实现的关系
3)接口与接口:多继承的关系
二.多态
1.理解:同一个对象有多种表现形态(数据类型,可以是父类类型,也可以是本类类型)
举例: Animal a = new Dog();a = new Cat();Dog d = new Dog();
2.多态的前提
(1)必须要有继承/实现的关系
(2)要有方法复写
(3)有父类引用变量指向子类(或实现类)对象
ps:在参数传递时,也可以体现多态的特性
3.多态的好处:【在定义一个方法时,把方法的参数写成父类类型,调用方法时可以传递任意的子类对象】
public class Demo {public static void main(String[] args) {//传入一个子类对象,用父类变量接收再使用父类方法调用animalEat(new Cat());animalEat(new Dog());}//好处,把方法的参数写成父类|接口类型,调用方法时,可以传递任意的子类对象public static void animalEat(Animal a){//Animal a =new Cat()//a =new Dog();a.eat();//传入一个用动物变量接收的狗类型对象if(a instanceof Cat){Cat cat = (Cat)a;cat.catchMouse();}if(a instanceof Dog){//强转简化方法((Dog)a).lookDoor();}}
}abstract class Animal {public abstract void eat();
}class Cat extends Animal{@Overridepublic void eat(){System.out.println("猫吃鱼");}//猫的特有方法public void catchMouse(){System.out.println("猫抓老鼠");}
}class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗吃骨头");}//狗的特有方法public void lookDoor(){System.out.println("狗看门");}
}打印结果:
猫吃鱼
猫抓老鼠
狗吃骨头
狗看门
4.多态的弊端【不能直接调用子类的特有方法,除非向下转型(强制转换)】
(1)向上转型:其实就是多态的写法
如:Animal a = new Dog();
(2)向下转型:把父类类型转换为子类类型
如:Dog d = (Animal)a ;
(3)注意事项,向下转型可能出现类型转换异常(ClassCastExcetpion)
所以我们我们如果想让父类对应的转换达到预期,可以在转换之前加个判断
//instanceof可以用来判断对象是否可满足某个特定类型
if(a instanceof Dog){//强转简化方法((Dog)a).lookDoor();}