复习过程中发现还有一部分内容去年寒假学习时未涉及到,需要继续学习
接口
public interface 接口名 {
//常量
String SCHOOL_NAME = "XMU"
//public static final String SCHOOL_NAME = "XMU"
//抽象方法
void run();
//public abstract void run();
}
- 接口体现规范思想,public static final 和 public abstract 可以省略
- JDK8之前接口中只能是常量和抽象方法
接口被类实现
单实现
//定义一个接口
public interface SportMan {
void run();
void competition();
}
//定义接口的实现类
public class PingPangMan implements SportMan{
@Override
public void run() {
}
@Override
public void competition() {
}
}
多实现
//再定义一个接口
public interface Law {
void rule();
}
//接口被类多实现
public class PingPangMan implements SportMan,Law{
@Override
public void run() {
}
@Override
public void competition() {
}
@Override
public void rule() {
}
}
接口与接口:多继承
作用: 整合多个接口为同一个接口,便于子类实现
定义两个接口:Law 和 People
public interface Law {
void rule();
}
public interface People {
void eat();
void sleep();
}
定义SportMan接口,继承Law 和 People
public interface SportMan extends Law,People {
void run();
void competition();
}
实现SportMan接口(相当于implements SportMan,Law,People)
public class BasketBallMan implements SportMan{
@Override
public void rule() {}
@Override
public void eat() {}
@Override
public void sleep() {}
@Override
public void run() {}
@Override
public void competition() {}
}
接口新增方法
JDK1.8开始:允许接口中定义带有方法体的方法
JDK1.9开始:允许接口中定义私有方法
public interface TestInter {
//默认方法
default void testDefault() {
System.out.println("Default");
testPrivate();//类内部调用静态方法
}
//静态方法
static void testStatic() {
System.out.println("Static");
}
//私有方法
private void testPrivate() {
System.out.println("Private");
}
}
class myTest implements TestInter {
//接口的实现类
}
class Test {
public static void main(String[] args) {
myTest t = new myTest();
t.testDefault();//通过实现类的对象调用默认方法
TestInter.testStatic();//通过接口调用静态方法
}
}
1.默认方法
- 必须用default修饰,默认pubic修饰
- 需要实现类的对象来调用
default void run() { System.out.println("开始跑"); }
2.静态方法
- 必须用static修饰,默认public修饰
- 接口的静态方法必须用本身的接口名来调用
static void run() { System.out.println("开始跑"); }
3.私有方法(JDK1.9)
- 必须使用private修饰
- 只能在本类中被其他的默认方法或者私有方法访问
private void run() { System.out.println("开始跑"); }
接口注意事项
- 一个类继承了父类,同时又实现了接口,父类和接口有同名方法时默认用父类的
- 一个类实现多个接口时,多个接口有同名的静态方法不冲突
- 一个类实现了多个接口,多个接口中存在同名的默认方法不冲突,类重写该方法即可
多态
多态的形式
形式
- 父类类型 对象名称 = new 子类构造器;
- 接口 对象名称 = new 实现类构造器;
访问特点
- 方法调用:编译看左边,运行看右边
- 变量调用:编译看左边,运行也看左边
//Dog,Tortoise extends Animal
Animal a1 = new Dog();
Animal a2 = new Tortoise();
//方法调用:编译看左边,运行看右边
a1.run();// Dog run
a2.run();// Tortoise run
//变量调用:编译看左边,运行也看左边
System.out.println(a1.name); //打印Animal name
System.out.println(a2.name); //打印Animal name
多态的优势
- 多态形式下,右边对象可以解耦合,便于扩展和维护
Animal a = new Dog();//可以直接替换为Animal a = new Cat(),不影响后续代码 a.run();
- 定义方法的时候,使用父类型作为参数,该方法就可以接收这个父类对象的一切子类对象
public static void competation(Animal s) { a.run(); } //调用 Dog dog = new Dog();//或Animal dog = new Dog(); Cat cat = new Cat(); competition(dog); competition(cat);
多态下引用数据类型的类型转换
问题:多态下不能使用子类独有的功能
- 自动类型转换(从子到父):子类对象赋值给父类类型
- 强制类型转换(从父到子)
形式:子类 对象变量 = (子类)父类类型的变量
作用:解决多态下的劣势,实现调用子类特有的功能
//自动类型转换:
Animal a = new Tortoise();
a.run(); //run是父类定义的方法
a.layEggs(); //下蛋是独有方法,报错
//强制类型转换
Tortoise t = (Tortoise) a;
t.layEggs(); //正常运行
Java建议强制转换前使用instanceof判断当前对象的真实类型,再进行强制转换
public static void act(Animal a) {
if (a instanceof Tortoise t)
t.layEggs();
else if (a instanceof Dog d)
d.lookDoor();
}