JAVA零基础小白学习教程之day08_接口多态
创始人
2024-04-28 06:35:51
0

day08-JAVAOOP

课程目标

1. 【理解】什么是接口
2. 【掌握】接口的定义格式
3. 【掌握】接口的使用
4. 【理解】接口的成员特点
5. 【理解】类和接口 抽象类和接口之间的关系
6. 【掌握】单继承多实现 
7. 【理解】接口之间的多继承
8. 【掌握】接口的案例 9. 【理解】什么是多态
10. 【理解】使用多态的前提
11. 【掌握】多态的格式
12. 【理解】多态中的成员访问特点
13. 【理解】多态中的好处和弊端
14. 【理解】多态中的转型
15. 【理解】转型的异常
16. 【掌握】综合案例

接口

接口基本概述及语法

接口概述

接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法(功能),包含抽象方法 、默认方法和静态方法、私有方法。

  • 概念

接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用。都可以参与进来进行编码,java就是面向接口的编程。

Java中的接口更多的体现在对行为的抽象!

接口语法

接口用关键字interface修饰

public interface 接口名 {} 

接口的使用

接口是不能创建对象,必须有实现类才能使用,类实现接口用implements表示。

public class 类名 implements 接口名 {}

接口成员的特点

成员变量

只能是常量,默认修饰符:public static final

成员方法

只能是抽象方法,默认修饰符:public abstract

构造方法

无,因为接口主要是扩展功能的,而没有具体存在

代码演示

  • 接口

    public interface Inter {//接口只能是常量//默认修饰符:public static finalpublic int num1 = 10;public final  int num2 = 20;public static final int num3 = 30;int num4 = 40;//接口没有构造方法// public Inter() {}//接口中不能有方法主体// public void show() {}//默认修饰符:public abstract public abstract void method1();public void method2();void show();
    }
    
  • 实现类

    //子类可以是抽象类。但是意义不大
    public abstract class InterImpl extends Object implements  Inter {}
    /***   字类是具体类,要实现接口中所有的抽象方法*   所有类都默认继承Object类,Object类是所有类的超类*/
    public class InterImpl extends Object implements  Inter {public InterImpl(){super();//所有super走得是object类} @Overridepublic void method1() {System.out.println("实现类中的method1");}@Overridepublic void method2() {System.out.println("实现类中的method2");}@Overridepublic void show() {System.out.println("实现类中的show");}
    }
    
  • 测试类

    public class Test {public static void main(String[] args) {//接口不能实例化// Inter i = new Inter();//通过多态的方法实Inter i = new InterImpl();//访问成员变量System.out.println(i.num1);//接口的常量是不能修改的// i.num1 = 100;i.method1();i.method2();i.show();}
    }
    

类与接口的关系

类与类:继承关系,只能单继承,不能多继承,可以多层继承(Father son sun)。extends 	
接口与接口:继承关系,可以单继承也可以多继承。public interface Sister extends I1,I2 类与接口:实现关系,可以单实现,也可以多实现。 public class Son extends Object implements I1,I2 并且还可以在继承一个类的同时实现多个接口。

抽象类和接口的区别

A:成员区别抽象类:成员变量:可以变量,也可以常量构造方法:有抽象类不能实现化成员方法:可以抽象,也可以非抽象接口:成员变量:只可以静态常量  可以省略 static final构造方法:无接口不能实例化成员方法:只可以抽象     可以省略abstract
B:关系区别类与类继承,单继承, 多层继承类与接口实现,单实现,多实现接口与接口继承,单继承,多继承C:设计理念区别抽象类【共性功能】。一般父类抽象接口【扩展功能】。 方法集合

继承父类并实现多个接口

之前学过,在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口。

多实现语法

class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {    // 重写接口中抽象方法【必须】// 重写接口中默认方法【不重名时可选】
} 

代码演示

  • 定义接口

    interface A {public abstract void showA();   public abstract void show();
    }
    interface B {public abstract void showB();   public abstract void show();
    }
    
  • 定义父类

    public class Fu{}
    
  • 定义实现类

    public class C extends Fu implements A,B{@Overridepublic void showA() {System.out.println("showA");    }@Overridepublic void showB() {System.out.println("showB");    }@Overridepublic void show() {System.out.println("show");    }
    }
    
  • 注意事项

    接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次即可!
    如果实现类继承了父类,这个父类是一个抽象类时,我们还需要再重写抽象类中的所有抽象方法。

接口之间的多继承

一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。如果父接口中的默认方法有重名的,那么子接口需要重写一次。

  • 定义父接口

    interface A {public void method1();
    }
    interface B {public void method2();
    }
    
  • 定义子接口

    interface D extends A,B{public void method2();
    }
    
  • 注意

    接口多继承之后,如果想使用,我们还必须定义实现类,才能使用
    

接口小结

  • 接口中只有常量和抽象方法
  • 接口是没有静态代码块和构造方法的。
  • 一个类的直接父类是唯一的,但是一个类可以同时实现多个接口。 单继承多实现
    public class MyInterfaceImpl implements MyInterfaceA, MyInterfaceB {// 覆盖重写所有抽象方法
    }
    
  • 如果实现类所实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可。
  • 如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类。

接口案例-TODO

  • 需求

    对猫和狗进行训练,他们就可以跳高了,这里加入跳高功能。

    请采用抽象类和接口来实现猫狗案例,并在测试类中进行测试。

  • 代码实现

    • Animal类
      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 String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public abstract void eat();
      }
      
    • 跳高接口Jumping
      public interface Jumpping {public abstract void jump();
      

    }

    
    * ##### 猫类(Cat)```java
    //子类继承 抽象类,实现接口
    public class Cat extends Animal implements Jumpping {public Cat() {}public Cat(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("猫吃鱼");}@Overridepublic void jump() {System.out.println("猫可以跳高了");}
    }
    
    • 测试类
      public class AnimalDemo {public static void main(String[] args) {Cat c = new Cat();c.setName("加菲");c.setAge(5);System.out.println(c.getName()+","+c.getAge());c.eat();c.jump();}
      }
      

多态

龙生九子

公司:老板下令,开始干活儿;

行政人员、程序猿、财务人员、市场人员;干活,不一样;

什么是多态

多态是继封装、继承之后,面向对象的第三大特性。对象的多种形态。

  • 定义:同一个对象,在不同时刻表现出来的行为是不同的。

前提条件

1.要有继承或实现关系
2.要有方法的重写
3.要有父类引用指向子类对象   fu  f = new zi();

多态中的成员访问特点

Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明决定该变量使用的类型,运行时类型由实际赋给该变量的对象决定。简称:编译时,看左边;运行时,看右边。
若编译时类型和运行时类型不一致,就出现了对象的多态性, 多态情况下,
“看左边” :看的是父类的引用(父类中不具备子类特有的方法)
“看右边”:看的是子类的对象(实际运行的是子类重写父类的方法)

编译看左边(父类),运行看右边(子类)

代码演示

  • 动物类(Animal)
    public class Animal {public int age = 40;public void eat() {System.out.println("动物吃东西");}
    }
    
  • 猫类(Cat)
    public class Cat extends Animal {public int age = 20;public int weight = 10;//子类要重写父类中的方法@Overridepublic void eat() {System.out.println("猫吃鱼");}public void playGame() {System.out.println("猫捉迷藏");}
    }
    
  • 测试类
    public class AnimalDemo {public static void main(String[] args) {//有父类引用指向子类对象Animal a = new Cat();//成员变量//编译看左边(父类),运行看左边(父类)System.out.println(a.age);// System.out.println(a.weight);//成员方法//编译看左边(父类),运行看右边(子类)a.eat();// a.playGame();}
    }
    

多态的好处和弊端

多态的好处

提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作。

多态的弊端

不能使用子类的特有成员

多态的好处代码演示

实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与便利

  • 定义父类
    public abstract class Animal {      public abstract void eat();
    }  
    
  • 定义子类
    class Cat extends Animal {  public void eat() {  System.out.println("吃鱼");  }  
    } 
    class Dog extends Animal {  public void eat() {  System.out.println("吃骨头");      }  
    }
    
  • 定义测试类
    public class Test {public static void main(String[] args) {        // 多态形式,创建对象Cat c = new Cat();  Dog d = new Dog(); // 调用showCatEat showCatEat(c);// 调用showDogEat showDogEat(d); /*多态的好处: 以上两个方法, 均可以被showAnimalEat(Animal a)方法所替代,而执行效果一致*/showAnimalEat(c);showAnimalEat(d); }public static void showCatEat (Cat c){c.eat(); }public static void showDogEat (Dog d){d.eat();}public static void showAnimalEat (Animal a){a.eat();}
    }
    

多态的好处小结

​ 由于多态特性的支持,showAnimalEat方法的Animal类型,是Cat和Dog的父类类型,父类类型接收子类对象,当然可以把Cat对象和Dog对象,传递给方法。当eat方法执行时,多态规定,执行的是子类重写的方法,那么效果自然与showCatEat、showDogEat方法一致,

​ 所以showAnimalEat完全可以替代以上两方法。

​ 不仅仅是替代,在扩展性方面,无论之后再多的子类出现,我们都不需要编写showXxxEat方法了,直接使用showAnimalEat都可以完成。

​ 所以,多态的好处,体现在,可以使程序编写的更简单,并有良好的扩展。

多态中的转型

为什么要用转型

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法。编译都错误,更别说运行了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子类特有的方法,必须做向下转型。

向上转型

子类的对象可以被当做基础的对象称为向上对象。系统默认。

  • 使用格式
    向上转型父类类型  变量名 = new 子类类型();
    如:Animal a = new Cat();
    

向下转型

父类类型向子类类型向下转换的过程,这个过程是强制的。

一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。

  • 使用格式
    子类类型 变量名 = (子类类型) 父类变量名;
    如:Cat c =(Cat) a;  
    

代码演示

  • 定义类
    abstract class Animal {  abstract void eat();  
    }  class Cat extends Animal {  public void eat() {  System.out.println("吃鱼");  }  public void catchMouse() {  System.out.println("抓老鼠");      }  
    }  class Dog extends Animal {  public void eat() {  System.out.println("吃骨头");     }  public void watchHouse() {  System.out.println("看家");  }  
    }
    
  • 测试类
    public class Test {public static void main(String[] args) {// 向上转型     fu f = new zi()Animal a = new Cat();  a.eat();                     // 调用的是 Cat 的 eat// 向下转型    zi z = (zi)fu; Cat c = (Cat)a;       c.catchMouse();              // 调用的是 Cat 的 catchMouse     }
    }  
    

转型的异常

问题描述

转型的过程中,一不小心就会遇到这样的问题,请看如下代码:

 public class Test {public static void main(String[] args) {// 向上转型  Animal a = new Cat();  a.eat();        // 调用的是 Cat 的 eat// 向下转型 Cat c = (Cat)a;c.catchMouse();//调用自己的方法System.out.println("================");// 向下转型  Dog d = (Dog)a;       //引用的父类,是多态cat类,并不是dogd.watchHouse();        // 调用的是 Dog 的 watchHouse 【运行报错】    }  
}

这段代码可以通过编译,但是运行时,却报出了ClassCastException类型转换异常!这是因为,明明创建了

Cat类型对象,运行时,当然不能转换成Dog对象的。这两个类型并没有任何继承关系,不符合类型转换的定义。

为了避免ClassCastException的发生,Java提供了instanceof关键字,给引用变量做类型的校验,格式如下:

instanceof使用格式

变量名 instanceof 数据类型 如果变量属于该数据类型,返回true。如果变量不属于该数据类型,返回false。

instanceof代码演示

public class Test {public static void main(String[] args) {// 向上转型  Animal a = new Cat();  a.eat();               // 调用的是 Cat 的 eat// 向下转型  if (a instanceof Cat){Cat c = (Cat)a;       c.catchMouse();        // 调用的是 Cat 的 catchMouse        } else if (a instanceof Dog){Dog d = (Dog)a;       d.watchHouse();       // 调用的是 Dog 的 watchHouse}}  
}

综合案例-TODO

案例需求

我们现在有乒乓球运动员和篮球运动员,乒乓球教练和篮球教练。

​ 为了出国交流,跟乒乓球相关的人员都需要学习英语。

​ 请用所学知识分析,这个案例中有哪些具体类,哪些抽象类,哪些接口,并用代码实现。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yIATmfsv-1671668242460)(assets/01.png)]

代码实现

  • Person类

    public abstract class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public abstract void eat();
    }
    
  • 抽象运动员类(Player)

    public abstract class Player extends Person {public Player() {}public Player(String name, int age) {super(name, age);}public abstract void study();
    }
    
  • 抽象教练类(Coach)

    public abstract class Coach extends Person {public Coach() {}public Coach(String name, int age) {super(name, age);}public abstract void teach();
    }
    
  • 学英语接口(SpeakEnglish)

    public interface SpeakEnglish {public abstract void speak();
    }
    
  • 蓝球教练(BasketballCoach)

    public class BasketballCoach extends Coach {public BasketballCoach() {}public BasketballCoach(String name, int age) {super(name, age);}@Overridepublic void teach() {System.out.println("篮球教练教如何运球和投篮");}@Overridepublic void eat() {System.out.println("篮球教练吃羊肉,喝羊奶");}
    }
    
  • 乒乓球教练(PingPangCoach)

    public class PingPangCoach extends Coach implements SpeakEnglish {public PingPangCoach() {}public PingPangCoach(String name, int age) {super(name, age);}@Overridepublic void teach() {System.out.println("乒乓球教练教如何发球和接球");}@Overridepublic void eat() {System.out.println("乒乓球教练吃小白菜,喝大米粥");}@Overridepublic void speak() {System.out.println("乒乓球教练说英语");}
    }
    
  • 乒乓球运动员(PingPangPlayer)

    public class PingPangPlayer extends Player implements SpeakEnglish {public PingPangPlayer() {}public PingPangPlayer(String name, int age) {super(name, age);}@Overridepublic void study() {System.out.println("乒乓球运动员学习如何发球和接球");}@Overridepublic void eat() {System.out.println("乒乓球运动员吃大白菜,喝小米粥");}@Overridepublic void speak() {System.out.println("乒乓球运动员说英语");}
    }
    
  • 篮球运动员(BasketballPlayer)

    public class BasketballPlayer extends Player {public BasketballPlayer() {}public BasketballPlayer(String name, int age) {super(name, age);}@Overridepublic void study() {System.out.println("篮球运动员学习如何运球和投篮");}@Overridepublic void eat() {System.out.println("篮球运动员吃牛肉,喝牛奶");}
    }
    

Player(String name, int age) {
super(name, age);
}

  @Overridepublic void study() {System.out.println("乒乓球运动员学习如何发球和接球");}@Overridepublic void eat() {System.out.println("乒乓球运动员吃大白菜,喝小米粥");}@Overridepublic void speak() {System.out.println("乒乓球运动员说英语");}

}


* #### 篮球运动员(BasketballPlayer)```java
public class BasketballPlayer extends Player {public BasketballPlayer() {}public BasketballPlayer(String name, int age) {super(name, age);}@Overridepublic void study() {System.out.println("篮球运动员学习如何运球和投篮");}@Overridepublic void eat() {System.out.println("篮球运动员吃牛肉,喝牛奶");}
}

相关内容

热门资讯

los系统和安卓系统的区别,两... 你有没有想过,为什么你的手机有时候运行得那么顺畅,有时候又卡得像蜗牛呢?这背后其实隐藏着两个大玩家—...
安卓系统可以安装cad软件,安... 你有没有想过,在安卓手机上也能轻松安装CAD软件呢?没错,就是那个专业的设计软件,以前只能在电脑上操...
车载ce系统与安卓系统的区别,... 你有没有想过,为什么你的车载系统有时候那么不智能,而安卓手机却总能给你带来惊喜?今天,就让我带你深入...
苹果6s系统换安卓系统,体验安... 你有没有想过,把你的苹果6s换成安卓系统呢?想象那流畅的触控体验,加上安卓那丰富的应用和可定制的界面...
安卓转移ios健康系统,探索健... 你有没有想过,从安卓手机转到iOS设备后,那些积累的健康数据怎么办呢?别急,今天就来给你详细解析如何...
安卓系统如何换微信号,教你如何... 你是不是也和我一样,对安卓系统换微信号这个话题感兴趣呢?毕竟,谁不想偶尔换个心情,换个昵称呢?好啦,...
安卓机清理系统内存,提升手机运... 手机用久了是不是感觉越来越卡?别急,今天就来教你怎么给安卓机清理系统内存,让你的手机焕发新生!一、内...
安卓子系统要求CPU,安卓子系... 你知道吗?最近在安卓系统圈子里,有个话题可是热得不得了,那就是安卓子系统对CPU的要求。这可不是小事...
安卓系统排名第几,引领智能时代... 你知道吗?在智能手机的世界里,有一个系统可是当之无愧的“王者”——那就是安卓系统!今天,就让我带你一...
阿里云是不是安卓系统,引领安卓... 最近是不是有很多小伙伴在问:“阿里云是不是安卓系统?”这个问题可真是让人好奇啊!咱们就来好好探讨揭开...
安卓系统音量调节的文件,安卓系... 你有没有遇到过这种情况:手机音量调得刚刚好,突然间就变得忽高忽低,让人听得心烦意乱?别急,今天就来跟...
平板刷安卓10原生系统,平板新... 你有没有想过,你的平板电脑也能拥有安卓10的原生系统呢?没错,就是那个流畅又强大的系统,现在它也能在...
安卓系统怎么设定位手机,安卓系... 你有没有想过,你的安卓手机是怎么知道你在哪儿的呢?没错,就是定位功能!这可是现代智能手机的一大亮点,...
升级的安卓系统怎样降级,安卓系... 你有没有遇到过这种情况?手机里的安卓系统突然升级了,结果发现新系统有点小bug,或者某些功能变得不那...
安卓刷机怎么升级系统,轻松实现... 你有没有发现,你的安卓手机最近有点儿慢吞吞的,是不是也想给它来个“大变身”,让它焕发新生呢?没错,刷...
安卓系统迷你小音响,便携式音乐... 你有没有想过,在忙碌的生活中,给自己一个小小的音乐角落,让心情随着音符跳动呢?今天,就让我带你走进一...
老安卓系统怎么删除页面,老安卓... 你有没有发现,手机里的安卓系统用久了,页面上的应用图标就像小山一样堆得高高的?有时候,看着这些图标,...
安卓手机死屏重置系统,轻松解决... 手机突然死屏了,是不是心里一紧?别慌,今天就来跟你聊聊安卓手机死屏后如何重置系统,让你轻松解决这个小...
安卓系统高怎么运行,解锁流畅体... 手机里的安卓系统突然变得卡顿起来,是不是让你感觉像是在迷宫里找出口?别急,今天就来给你支几招,让你的...
安卓系统新消息弹屏,体验升级 你知道吗?最近安卓系统又来了一大波新消息,这可真是让人兴奋不已!想象当你正在专心致志地刷着手机,突然...