【JAVA OOP】Day09 抽象方法、抽象类、接口、引用类型数组


Day09目标:

  • 理解抽象方法、抽象类的应用场景;

  • 掌握抽象方法、抽象类的语法;

  • 理解接口的应用场景;

  • 掌握接口的语法、应用;

  • 掌握引用类型数组的用法;

  • 代码量:课上120行,课下240行。


抽象类和接口

抽象类

设计规则

  • 适合初学者:共3点

    • 将子类共有的属性和行为,抽到父类 —— 抽取共性的

    • 若子类的行为或代码和父类都一样,设计普通方法;若子类的行为或父类代码和父类不一样,设计为抽象方法

    • ???

抽象方法、抽象类

Animal类:

public class Animal {
  String name;
  int age;
  String color;
  Animal(){
  }
  Animal(String name, int age, String color){...}
}

喝水方法(行为都一样 —— 普通方法

void drink() {
  System.out.println(color + "色的" + age + "岁的" + name + "正在喝水");
}

吃饭方法(行为不一样 —— 抽象方法

void eat() {
    System.out.println(color + "色的" + age + "岁的" + name + "正在吃饭");
}
  • 由abstract修饰,只有方法的定义,没有具体的实现(连{}都没有)

    • 包含抽象方法的类必须是抽象类,抽象类由abstract修饰

Animal类

public abstract class Animal { // 不完整
  String name;
  int age;
  String color;
  Animal(){
  }
  Animal(String name, int age, String color){...}
}

void drink(){
  System.out.println(color + "色的" + age + "岁的" + name + "正在喝水");
}
abstract void eat();  // 不完整,因为没有方法体
  • 抽象类不能被实例化(new对象)—— 单独存在没有意义
    Animal animal = new Animal();  // 编译错误
  • 抽象类是需要被继承的
  abstract class Animal{
    name, age, color
    void drink(){}
    abstract void eat();
  }
  class Dog extends Animal{ // 编译错误
  }
  class Chick extends Animal{
  }
  • 抽象类是需要被继承的,子类:

    • 也声明为抽象类

    • 重写所有方法 —— 变不完整为完整

  abstract class Animal{
    name, age, color
    void drink(){...}
    abstract void eat();
  }
  class Dog extends Animal{
    void eat(){
      System.out.println(color + "色的" + age + "岁的狗狗" + name + "正在吃骨头!")
    }
  }
  class Chick extends Animal{
    System.out.println(color + "色的" + age + "岁的小鸡" + name + "正在吃小米!");
  }

设计抽象方法的原因

  • 真实的项目都是团队协作完成的

    • 假设不设计抽象方法:

      • 张光设计Dog类,吃的方法名称为eat()

      • 李林设计Chick类,吃的方法名称为eating()

      • 赵亮设计Fish类,吃的方法名称为ate()

      • 孙其想让动物们吃饭 —— 需要记3个名字,还得与动物对应 → 麻烦

    • 假设设计抽象方法eat表示吃:

      • 张光设计Dog类,吃的方法只能叫eat(),必须重写

      • 李林设计Chick类,吃的方法只能叫eat(),必须重写

      • 赵亮设计Fish类,吃的方法只能叫eat(),必须重写

      • 孙其想让动物们吃饭 —— 需要记1个名字,不用区分动物 → 方便

抽象类的意义

  • 封装共有的属性和行为 —— 实现代码复用

  • 可以包含抽象方法:

    • 为子类提供统一的入口(名字统一)

    • 强制必须重写

接口

设计规则

  • 适合初学者:共3点(新老交替)

    • 所有子类共有的属性和行为,抽到父类中 —— 抽共性

    • 若子类的行为/代码都不一样,设计普通方法;若子类的行为/代码不一样,设计抽象方法

    • 部分子类有共有的行为,抽到接口

接口的应用

  • 在现有案例基础之上,添加如下需求:

    • 游泳

    • 游泳

    • 不会游泳

    在这里插入图片描述

  • 我们之前将父类理解成“亲爹”,而现在可以把接口理解成“干爹”。接口一般表示为:“具备某种功能”。

  • 接口的应用:

    • 接口是对继承单根性(单一继承)的扩展 —— 实现多继承

    • 接口是一种标准、规范,表述具备某种功能。实现了某接口就具备某个功能,不实现接口就不具备那个功能。

接口的语法

  • 接口是一种引用数据类型

  • 由interface定义

  • 目前内容而言,只能包含抽象方法(之后讲常量、默认方法、静态方法、私有方法

interface Inter {
  abstract void show();
  void test(); // 接口中的方法默认都是抽象的,前面已经默认有abstract了
  // void say(){}     // 抽象方法不能有方法体
}
  • 接口不能被实例化(new对象)
Inter o = new Inter();  // 编译错误,接口不能被实例化
  • 接口是需要被实现的,实现类必须重写接口中的所有抽象方法。注意:重写接口中的方法时必须加public
interface Inter{
  abstract void show();
  void test();
}
class InterImpl implements Inter{
  public void show(){
  }
  public void test(){
  }
}

接口的特点

  • 一个类可以实现多个接口,以逗号分隔

  • 若又继承又实现时,必须先继承后实现

interface Inter1{
  void show();
}
interface Inter2{
  void test();
}
abstract class Aoo{
  say();
}
class Boo extends Aoo implements Inter1, Inter2{
  @Override
  public void show();
  @Override
  public void test();
  @Override
  void say();  // 前面public可写可不写
}
  • 接口可以继承接口
interface Inter3{
  void show();
}
interface Inter4 extends Inter3{
  void test();
}
class Coo implements Inter4{
  public void test(){}
  public void show(){}
}

(类与类 —— 继承)

(接口与接口 —— 继承)

(类与接口 —— 实现)

引用类型数组

什么是引用类型数组?

  • 引用类型数组:数组元素为引用类型的数组

    • 存储10名学生:Student[] student = new Student[10];

    • 存储3只小狗:Dog[] dogs = new Dog[3]; 声明Dog型数组,包含3个元素;每个元素都是Dog类型,默认值为null

    • 存储5辆汽车:Car[] cars = new Car[5];

引用类型数组特点

  • 引用类型数组与基本类型数组,有两点区别

    • 给引用类型数组的元素赋值时,需要new个对象
    int[] arr = new int[3];  // 基本类型数组
    arr[0] = 100;
    
    Dog[] dogs = new Dog[3]; // 引用类型数组 ——— 创建Dog数组对象
    dogs[0] = new Dog("小黑", 2, "黑"); // 创建Dog对象
    
    • 访问引用类型数组元素的属性/行为时,需要打点访问
    Dog[] dogs = new Dog[3];
    dogs[0] = new Dog("小黑", 2, "黑");
    dogs[1] = new Dog("小白", 1, "白");
    dogs[2] = new Dog("小灰", 3, "灰");
    // 输出第一只狗狗的名字
    System.out.println(dog[0].name);
    // 第3只狗狗游泳
    dogs[2].swim();
    
    属性:name、age、color
    行为:eat()drink()lookHome()swim()
    
  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值