接口
什么是接口?
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。 接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。 除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。 接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。 另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口的定义格式
public interface 接口名 {}
注意:接口不能创建对象,必须有实现类才能使用,类实现接口用implements表示;接口的实现类必须重写接口中的所有抽象方法,要么该类是一个抽象类。
接口成员的特点
成员变量:只能是常量,默认修饰符:public static final
成员方法:只能是抽象方法,默认修饰符:public abstract
构造方法:没有构造方法,因为接口主要是扩展功能的,而没有具体存在
//接口
public interface Inter {
public int num = 10;
public final int num2 = 20;
//接口中无构造方法
//public Inter(){}
//接口中无具体方法
//public void show(){}
public abstract void method();
//抽象方法默认为 public abstract
void show();
}
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 16:45
*/
public class InterImpl implements Inter {//接口实现类
public InterImpl(){
super();
}
@Override
public void method() {
System.out.println("method");
}
@Override
public void show() {
System.out.println("show");
}
}
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 16:46
*/
public class test {
public static void main(String[] args) {//测试类
Inter inter = new InterImpl();
//inter.num = 20;
System.out.println(inter.num);
//inter.num2 = 40;
System.out.println(inter.num2);
System.out.println(Inter.num);
}
}
接口与类的关系
类与类的关系:继承关系,只能是单继承,但是可以多层继承
类与接口的关系:实现关系,可以单实现,也可以继承一个类同时实现多个接口
接口与接口的关系:继承关系,可以单继承,也可以多继承
抽象类与接口的区别
成员区别
抽象类:有变量、常量;构造方法;抽象方法;非抽象方法
接口:常量;抽象方法
关系区别
类与类:继承,单继承
类与接口:实现,可以但实现,也可以多实现
接口与接口:继承,单继承,多继承
设计理念区别
抽象类:为了继承而来,让子类强制重写父类的抽象方法
接口:对行为抽象,主要是行为
继承父类并实现多个接口
实现格式:
class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【不重名时可选】
}
代码演示:
//接口A
public interface A {
public abstract void showA();
void show();
}
//接口B
public interface B {
void showB();
void show();
}
//父类
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 16:53
*/
public class Fu {
}
//实现类
/**
* @Describe 继承父类实现多个接口
* @Author Double LiFly
* @date 2021/4/8 16:53
*/
public class C extends Fu implements A,B {
/**
* 接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次即可!
* 如果实现类继承了父类,这个父类是一个抽象类时,我们还需要再重写抽象类中的所有抽象方法。
*/
@Override
public void showA() {
System.out.println("showA");
}
@Override
public void showB() {
System.out.println("showB");
}
@Override
public void show() {
System.out.println("Show");
}
}
接口之间的多继承
代码演示:
//接口A
public interface A {
public void methodA();
}
//接口B
public interface B {
void methodB();
}
//接口C
/**
* 接口多继承之后,如果想使用,我们还必须定义实现类,才能使用
*/
public interface C extends A,B {
void methodC();
}
接口小结
接口中只有常量和抽象方法
接口是没有静态代码块和构造方法的
一个类的直接父类是唯一的,但是一个类可以同时实现多个接口,单继承多实现
如果实现类所实现的多个接口中,存在重复的抽象方法,那么只需要重写覆盖一次就好
如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么这个类就必须是一个抽象类
接口案例
对猫和狗进行训练,他们就可以跳高了,这里加入跳高功能。
请采用抽象类和接口来实现猫狗案例,并在测试类中进行测试
代码实现:
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:00
*/
public abstract class Animal {//抽象动物类
private String name;
private int age;
public Animal(){}
public Animal(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public abstract void eat();
}
public interface Jumpping {//接口
public abstract void jump();
}
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:04
*/
public class Cat extends Animal implements Jumpping {//实现类
public Cat(){}
public Cat(String name,int age){
super(name, age);
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void jump() {
System.out.println("猫可以跳高了");
}
}
//测试类
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:05
*/
public class test {
public static void main(String[] args) {
Cat cat = new Cat();
cat.setName("加菲");
cat.setAge(3);
System.out.println(cat.getName()+","+cat.getAge());
cat.eat();
cat.jump();
}
}
多态
多态是同一个行为具有多个不同表现形式或形态的能力。 多态就是同一个接口,使用不同的实例而执行不同操作
优点
1. 消除类型之间的耦合关系
2. 可替换性
3. 可扩充性
4. 接口性
5. 灵活性
6. 简化性
多态存在的三个必要条件
继承 重写 父类引用指向子类对象:Parent p = new Child(); 当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。 多态的好处: 可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
多态格式
普通类多态的格式
父类 对象 = new 子类();
抽象类多态的格式
抽象类 对象名 = new 抽象类子类();
接口多态的格式
接口 对象名 = new 接口实现类();
多态中的成员访问特点
成员变量
编译看父类,运行看父类
成员方法
编译看父类,运行看子类
猫狗案例:
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:18
*/
public abstract class Animal {
public abstract void eat();
}
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:18
*/
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("吃鱼");
}
}
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:19
*/
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("吃骨头");
}
}
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:19
*/
public class Test {
public static void main(String[] args) {
//多态形式创建对象
Cat cat = new Cat();
Dog dog = new Dog();
showCat(cat);
shwoDog(dog);
/*
以上两个方法, 均可以被showAnimalEat(Animal a)方法所替代
而执行效果一致
*/
showAnimal(cat);
showAnimal(dog);
}
public static void showCat(Cat cat){
cat.eat();
}
public static void shwoDog(Dog dog){
dog.eat();
}
public static void showAnimal(Animal animal){
animal.eat();
}
}
多态中的转型
为什么需要转型?
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法。编译都错误,更别说运行了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子类特有的方法,必须做向下转型。
向上转型
多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的
使用格式:
父类类型 变量名 = new 子类类型();
例如:Father father = new son();
向下转型
父类类型向子类类型向下转换的过程,这个过程是强制的。一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型
使用格式:
子类类型 变量名 = (子类类型)父类变量名;
例如:Cat cat = (Cat)animal;
instanceof使用格式
变量名 instanceof 数据类型
如果变量属于给数据类型,返回true
如果变量不属于该数据类型,返回false
综合案例
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:26
*/
public abstract class Animal {
abstract void eat();
}
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:26
*/
public class Cat extends Animal {
@Override
void eat() {
System.out.println("吃鱼");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:27
*/
public class Dog extends Animal {
@Override
void eat() {
System.out.println("吃骨头");
}
public void watchHouse(){
System.out.println("看家");
}
}
/**
* @Describe
* @Author Double LiFly
* @date 2021/4/8 17:28
*/
public class Test {
public static void main(String[] args) {
//向上转型
Animal animal = new Cat();
animal.eat();//调用的是Cat的eat
//向下转型
Cat cat = (Cat) animal;//调用的是Cat的catchMouse
cat.catchMouse();
//Dog dog = (Dog) animal;
// dog.watchHouse();//报错java.lang.ClassCastException转型异常
//Java提供了instanceof关键字,给引用变量做类型的校验
System.out.println("~~~~~~~~~~~");
if (animal instanceof Cat){
Cat cat1 = (Cat) animal;
cat1.catchMouse();
}else if (animal instanceof Dog){
Dog dog1 = (Dog) animal;
dog1.watchHouse();
}
}
}