Java第四章第1节:接口与内部类 之 接口 实验+图解讲解


简介

👨‍💻个人主页@云边牧风
👨‍🎓小编介绍:欢迎来到云边牧风破烂的小星球🌝
📋专栏:Java基础知识
🔑本章内容:Java接口与内部类
记得 评论📝 +点赞👍 +收藏😽 +关注💞哦~

今天开始学习第四章了,这一章的内容主要有👇:

4.1 接口

4.2 内部类

4.3 匿名类

4.4 异常类

4.5 Class

我们还是分为两到三节的篇幅,由浅入深地讲清楚以上内容;第一节:接口

一、接口

1.1接口的由来

前面讲到Java 不支持多继承性,即一个类只能有一个父类。单继承性使得 Java 简单,易于管理程序。为了克服单继承的缺点, Java 使用了接口,即一个类可以实现多个接口。

1.2接口的概念

    接口(英文:Interface),在Java中是一个抽象类型,是抽象方法的集合。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。(简单点理解就是类有方法有对象,但接口没对象

接口无法被实例化,但是可以被实现。

1.3接口的声明

格式: 

使用关键字 interface 来声明一个接口
格式:
interface  接口的名字

[可见度] interface 接口名字 [extends 其他的接口名] {      //需要用到[可见度]的话,

                                                                                             //[可见度]只能是public
        // 声明变量
        // 抽象方法
}

接口体:

与定义类相似,接口定义包括 声明 部分和 接口体

interface  Printable    //接口声明

//接口体

  final  int MAX=100;

   void add();

   float sum(float x ,float y);

}

1.4接口定义与类定义的区别:

成员变量 部分:接口中 只能定义常量
每个成员都默认是 public  static  final 无法改变
也正因为如此,上述关键字 可以省略)
方法 部分:接口中 只能定义抽象方法
每个方法都默认是 public  abstract 无法改变 。因此,接口体中只进行方法的声明,不许提供方法的实现
(也正因为如此,上述关键字 可以省略)

注意:上述关键字可以省略,但绝不能随意改动——改成默认之外的话就会报错!!!

二、接口的使用

2.1接口使用的格式

类通过使用关键字 implements 声明使用一个或多个接口;多个接口之间用逗号隔开。如:

class A  implements  Printable,Addable    //声明了两个接口:
                                                                                                 Printable和Addable
如果一个类 使用了某个接口,那么必须实现该接口的所有方法 ,否则,该类必须是抽象类
注意:实现接口方法时,必须加上 public

例如👇:

/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{
 
   public void eat(){
      System.out.println("Mammal eats");
   }
 
   public void travel(){
      System.out.println("Mammal travels");
   } 
 
   public int noOfLegs(){
      return 0;
   }
 
   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
}

执行结果是:

Mammal eats
Mammal travels

2.2接口的思想

思想: 可以定义很多类都需要实现的功能,而且不要求这些类之间有继承关系

 

即同一个类也可以实现多个接口。接口只关心功能,并不关心功能的具体实现

2.3接口的意义

接口存在的意义

实现了“多继承” 避免 了传统“多继承”的 复杂性
建立类和类之间的“ 协议 (这是最精辟的总结了)
一方面,使用接口 不需要考虑类的继承层次 问题
另一方面,可以实现不同类之间的 常量共享
允许在看起来不相干的对象之间定义共同行为

三、接口的具体示例
 

3.1保险公司

具有车辆保险、人员保险、公司保险等多种保险业务,这些类互不相干,但是都需要计算保险费 (premium) 等,因此可声明一个 Insurable 接口

 

关系图为👇: 

具体题目(OJ的测试题)为:

设计一个Car类,有一个车龄属性,构造函数初始化车龄

设计一个Company类,有个一个估值属性,构造函数初始化公司的估值

CarCompany都可以买保险,保险费车的是车龄乘以100,公司是估值除以100

设计一个Insurable接口,包括一个抽象方法getFee();

现在有个系统已经实现的People类中包含一个方法display(Insuable s),能够打印出输入参数的费用

根据下面测试样例的调用方式,你将如何设计?请完成类和接口的设计

 提交测试的代码为:

class People{
    public static void display(Insurable s){
        System.out.println(s.getFee());
    }
}
class Car implements Insurable{
    int age;
    public Car(int age){
        this.age = age;
    }
    public double getFee() {
        return age * 100;
    }
}
class Company implements Insurable{
    int value;
    public Company(int value){
        this.value = value;
    }
    public double getFee() {
        return value / 100;
    }
}
interface Insurable{
    double getFee();
}

OJ提交结果为:

3.2接口回调

3.1的保险公司代码中,代码出现了interface,前面还没讲到,这里补上:

定义:如果某个类实现了某接口,那么 可以将该类的对象的引用赋给该接口声明的变量中 。那么该接口变量就可以 调用被类实现的接口中的方法
即“对象的上转型”

如👇:

有代码

class Kitty implements Speakable {

    public void speak(){

        System.out.println("喵喵~");

    }

}

要使用speak方法时,加上

interface Speakable {

    void speak();

}

然后Main中就可以这样使用了:

Speakable s;

Kitty c = new Kitty();

s = c;                   //这里就是对象的上转型

s.speak();

下转型就是:

Speakable s;

Kitty c = new Kitty();

c = (Kitty)s;    //有种类型强制转换的感觉是不是?

c.speak();

3.3接口回调应用——做参数

如果方法的参数是接口类型,那么可以将任何实现该接口的类的实例传递给该接口参数,这样就可以通过接口回调调用具体方法

接口是抽象的,不能直接使用,但是如果传递参数时使用具体的对象,那么会非常麻烦, 使用接口作为参数简化了程序复杂性

例如

interface SpeakHello {
    void speakHello();
}
class Chinese extends People implements SpeakHello {
   public  void speakHello() {
       System.out.println("中国人习惯问候语:你好,吃饭了吗? ");
   }
}
class English extends People  implements SpeakHello {
    public  void speakHello() {
       System.out.println("英国人习惯问候语:你好,天气不错 ");
    }
}

 and

class KindHello {
   public void lookHello( SpeakHello hello  ) { //接口类型参数
       hello.speakHello();                    //接口回调
   }
}
public class Main{
   public static void main(String args[]) {
       KindHello kindHello=new KindHello();
       kindHello.lookHello(new Chinese());
       kindHello.lookHello(new English());
   }
}

 由此我们可以得出:

需要继承父类的非抽象特性,用抽象类
仅仅在多个类中实现某些公共方法,用接口

 

四、练习

设计一个动物声音“模拟器”,希望模拟器可以模拟许多动物的叫声,要求如下:

1. 编写接口Animal

      Animal接口有2个抽象方法cry()getAnimalName(),即要求实现该接口的各种具体动物类给出自己的叫声和种类名称。

2.编写模拟器类Simulator

      该类有一个playSound(Animal animal)方法,该方法的参数是Animal类型。即参数animal可以调用实现Animal接口类重写的cry()方法播放具体动物的声音,调用重写的getAnimalName()方法显示动物种类的名称。

3.编写实现Animal接口的DogCat

以上练习题,如果小伙伴们喜欢,可以在评论区求代码❤❤❤

结束语:

以上是Jav第四章第1节的全部内容,希望大家喜欢

下一节开始讲第四章第2节:内部类与匿名类

喜欢的可以点赞+关注哈 ❤

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云边牧风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值