【26天高效学习Java编程】Day12:设计模式基石----接口、多态、引用类型详解

本专栏将从基础开始,循序渐进,由浅入深讲解Java的基本使用,希望大家都能够从中有所收获,也请大家多多支持。
专栏地址:26天高效学习Java编程
相关软件地址:软件地址
所有代码地址:代码地址
如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。
如果感觉博主的文章还不错的话,还请关注、点赞、收藏三连支持一下博主哦

本文将详细讲解如下内容:

  • 接口
    • 定义接口
    • 实现接口
    • 接口中成员访问特点
  • 多态
    • 实现多态
    • 多态成员访问特点
    • 多态的好处和弊端
    • 解决弊端—引用类型转换
  • 内部类
    • 匿名内部类

文章目录

第一章 接口

知识点–3.1 概述

目标:

  • 引用数据类型除了类其实还有接口,接下来学习接口的概述

讲解:

概述: 接口是Java语言中的一种引用类型,是方法的"集合",所以接口的内部主要就是定义方法,包含常量,抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(jdk9)。

接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。

public class 类名{}–>.class

public interface 接口名{}->.class

引用数据类型:数组,类,接口。

接口的使用,它不能创建对象,但是可以被实现(implements ,类似于被继承)。一个实现接口的类(可以看做是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。

小结:

  • 接口是java语言中的一种引用数据类型
  • 接口中的成员:
    • 常量(jdk7及其以前)
    • 抽象方法(jdk7及其以前)
    • 默认方法和静态方法(jdk8额外增加)
    • 私有方法(jdk9额外增加)
  • 定义接口使用interface关键字—接口编译后产生class文件
  • 接口不能创建对象,需要使用实现类实现接口(类似于继承),实现接口的类叫做实现类(子类)

知识点–3.2 定义格式

目标:

  • 如何定义一个接口

讲解:

格式
public interface 接口名称 {
    // 常量(jdk7新增)
    // 抽象方法(jdk7新增)
    // 默认方法(jdk8新增)
    // 静态方法(jdk8新增)
    // 私有方法(jdk9新增)
}
案例
//函数的默认是public abstract,变量的类型是public static final,对于缺少的修饰符用默认的(对于prive则不能用abstract修饰,因为子类不能实现private函数,default和static只能拥一个,不能两个都用)。
public interface IA {
    // 常量(jdk7及其以前) 使用public static final关键字修饰,这三个关键字都可以省略
    public static final int NUM1 = 10;
    int NUM2 = 20;

    // 抽象方法(jdk7及其以前) 使用public abstract关键字修饰,这2个关键字可以省略一个,也可以都省略
    public abstract void method1();
    void method2();

    // 默认方法(jdk8) 使用public default关键字修饰,public可以省略,default不可以省略,接口提供一个默认实现的方法,并且不强制实现类重写此方法
    public default void method3(){
        System.out.println("默认方法 method3");
    }

    // 静态方法(jdk8) 使用public static关键字修饰,public可以省略,static不可以省略
    public static void method4(){
        System.out.println("静态方法 method4");
    }
    
    // 私有方法(jdk9) 使用private关键字修饰,private不可以省略
    private static void method5(){
        System.out.println("私有静态方法  method5");
    }

    //private不能使用abstract修饰,因为子类不能实现private的函数
    private void method6(){
        System.out.println("私有非静态方法  method6");
    }
}

知识点–3.3 实现接口

目标

  • 掌握什么是实现,以及如何实现接口

讲解

实现概述

类与接口的关系为实现关系,即**类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。**实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。

实现格式
  • 类可以实现一个接口,也可以同时实现多个接口。

    • 类实现接口后,必须重写接口中所有的抽象方法,否则该类必须是一个“抽象类”。

      public interface IA{
          public void show1();
      }
      public interface IB{
          public void show2();
      }
      public class Zi implements IA ,IB{
          public void show1(){
          }
          public void show2(){
          }
      }
      
  • 类可以在“继承一个类”的同时,实现一个、多个接口;

    public class Fu{}
    public interface IA{}
    public interface IB{}
    public class Zi extends Fu implements IA,IB{//一定要先继承,后实现
    }
    
    

知识点–3.4接口中成员的访问特点

目标

  • 掌握接口中成员访问特点

讲解

接口中成员访问特点概述
  接口中成员的访问特点:
                接口中的常量: 主要是供接口直接使用
                接口中的抽象方法: 供实现类重写的
                接口中的默认方法: 供实现类继承的(实现类中可以直接调用,实现类对象也可以直接调用)
                接口中的静态方法: 只供接口直接调用,实现类继承不了
                接口中的私有方法: 只能在接口中直接调用,实现类继承不了
案例演示
public interface IA {
    // 常量
    public static final int NUM = 10;

    // 抽象方法
    public abstract void method1();

    // 默认方法
    public default void method2(){
        //method4();
        //method5();
        System.out.println("IA 接口中的默认方法method2");
    }

    // 静态方法
    public static void method3(){
        //method5();
        System.out.println("IA 接口中的静态方法method3");
    }

    // 私有方法
    private void method4(){
        System.out.println("IA 接口中的私有方法method4");
    }

    private static void method5(){
        System.out.println("IA 接口中的私有方法method5");
    }
}



public class Imp implements IA {
    // 重写接口的抽象方法
    @Override
    public void method1() {
        System.out.println("实现类重写IA接口中的抽象方法");
    }

    // 重写接口的默认方法
    @Override
    public void method2() {
        System.out.println("实现类重写IA接口中的默认方法");
    }

}


public class Test {
    public static void main(String[] args) {
        /*
            接口中成员的访问特点:
                常量:主要是供接口名直接访问
                抽象方法:就是供实现类重写
                默认方法:就是供实现类重写或者实现类对象直接调用
                静态方法: 只供接口名直接调用
                私有方法: 只能在本接口中调用

         */
        // 访问接口常量
        System.out.println(IA.NUM);// 10  推荐
        //System.out.println(Imp.NUM);// 10 不推荐 常量被实现类继承了

        // 创建实现类对象调用方法
        Imp imp = new Imp();

        // 访问抽象方法
        imp.method1();

        // 访问默认方法
        imp.method2();

        // 接口名访问静态方法
        IA.method3();
        //Imp.method3();// 编译报错,没有继承
    }
}

小结

  • 接口中成员访问特点:
    • 常量:主要是供接口名直接访问
    • 抽象类:就是用来给实现类重写的
    • 默认方法:只供实现类重写或者实现类对象直接调用
    • 静态方法:只供接口名直接调用
    • 私有方法:只能在本接口中调用

知识点–3.5 多实现时的几种冲突情况

目标

  • 理解多实现时的几种冲突情况

讲解

公有静态常量的冲突
  • 实现类不继承冲突的常量
interface A{
    public static final int NUM1 = 10;
}
interface B{
    public static final int NUM1 = 20;
    public static final int NUM2 = 30;
}
class Imp implements A,B{

}
public class Test {
    public static void main(String[] args) {
        /*
            公有静态常量的冲突: 如果多个接口中有相同的常量,那么实现类就无法继承
         */
        //System.out.println(Imp.NUM1);// 编译报错,无法访问
        System.out.println(Imp.NUM2);// 30
    }
}

公有抽象方法的冲突
  • 实现类只需要重写一个
interface A{
    public abstract void method();
}
interface B{
    public abstract void method();
}
class Imp implements A,B{
    @Override
    public void method() {
        System.out.println("实现类重写");
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            公有抽象方法的冲突:实现类只需要重写一个 
         */
    }
}

公有默认方法的冲突
  • 实现类必须重写一次最终版本
interface A{
    public default void method(){
        System.out.println("A 接口的默认方法method");
    }
}
interface B{
    public default void method(){
        System.out.println("B 接口的默认方法method");
    }
}
class Imp implements A,B{
    @Override
    public void method() {
        System.out.println("实现类重写的默认方法");
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            公有默认方法的冲突:实现类必须重写一次最终版本 
         */
        Imp imp = new Imp();
        imp.method();
    }
}

公有静态方法的冲突
  • 静态方法是直接属于接口的,不能被继承,所以不存在冲突

    face A{
        public static void method(){
            System.out.println("A接口的静态方法method");
        }
    }
    interface B{
        public static void method(){
            System.out.println("B接口的静态方法method");
        }
    }
    class Imp implements A,B{
    
    }
    public class Test {
        public static void main(String[] args) {
            /*
                公有静态方法的冲突:静态方法是直接属于接口的,不能被继承,所以不存在冲突
             */
        }
    }
    
    
私有方法的冲突
  • 私有方法只能在本接口中直接使用,不存在冲突

小结

 多实现时的几种冲突情况:
                - 公有静态常量的冲突:实现类不继承冲突的常量
                - 公有抽象方法的冲突:实现类只需要重写一个
                - 公有默认方法的冲突:实现类必须重写一次最终版本
                - 公有静态方法的冲突:静态方法是直接属于接口的,不能被继承,所以不存在冲突
                - 私有方法的冲突:私有方法只能在本接口中直接使用,不存在冲突

知识点–3.6 接口和接口的关系

目标

  • 理解接口与接口之间的关系,以及接口继承时的冲突情况

讲解

接口与接口之间的关系
  • 接口可以“继承”自另一个“接口”,而且可以“多继承”。

    interface IA{}
    interface IB{}
    interface IC extends IA,IB{//是“继承”,而且可以“多继承”
    }
    
接口多继承接口的冲突情况
公有静态常量的冲突
  • 子接口无法继承父接口中冲突的常量
interface A{
    public static final int NUM1 = 10;
}
interface B{
    public static final int NUM1 = 20;
    public static final int NUM2 = 30;
}
interface C extends A,B{

}
public class Test {
    public static void main(String[] args) {
        /*
            公有静态常量的冲突: 子接口无法继承父接口中冲突的常量
         */
        //System.out.println(C.NUM1);// 编译报错,说明无法继承
        System.out.println(C.NUM2);// 30
    }
}

公有抽象方法冲突
  • 子接口只会继承一个有冲突的抽象方法
interface A{
    public abstract void method();
}
interface B{
    public abstract void method();
}
interface C extends A,B{

}
class Imp implements C{
    @Override
    public void method() {
        System.out.println("实现接口的抽象方法");
    }
}

public class Test {
    public static void main(String[] args) {
        /*
            公有抽象方法的冲突:子接口只会继承一个有冲突的抽象方法
         */
        Imp imp = new Imp();
        imp.method();
    }
}

公有默认方法的冲突
interface A{
    public default void method(){
        System.out.println("A 接口中的默认方法method");
    }
}
interface B{
    public default void method(){
        System.out.println("B 接口中的默认方法method");
    }
}

interface C extends A,B{

    @Override
    public default void method() {
        System.out.println("重写父接口中的method方法");
    }
}

class Imp implements C{

}

public class Test {
    public static void main(String[] args) {
        /*
            公有默认方法的冲突:子接口中必须重写一次有冲突的默认方法
            面试题:
                实现类重写接口中的默认方法,不需要加default
                子接口重写父接口中的默认方法,必须加default
         */
        Imp imp = new Imp();
        imp.method();// 重写父接口中的method方法
    }
}

公有静态方法和私有方法
  • 不冲突,因为静态方法是直接属于接口的,只能使用本接口直接访问,而私有方法只能在接口中访问,也没有冲突
interface A{
    public static void method(){
        System.out.println("A 接口的静态方法method");
    }
}
interface B{
    public static void method(){
        System.out.println("B 接口的静态方法method");
    }
}
interface C extends A,B{
    
}
public class Test {
    public static void main(String[] args) {
        /*
            公有静态方法的冲突: 不存在冲突,因为静态方法是直接属于接口的,只供本接口直接调用
         */
        //C.method();// 编译报错,因为没有继承
    }
}

小结

  - 接口与接口之间的关系: 继承关系
                    单继承: A接口继承B接口
                    多继承: A接口同时继承B接口,C接口,...
                    多层继承: A接口继承B接口,B接口,继承C接口
                    格式:
                        public interface 接口名 extends 接口名1,接口名2,...{
                            
                        }

- 接口多继承时的冲突情况
    - 公有静态常量的冲突:子接口无法继承父接口中冲突的常量
    - 公有抽象方法的冲突:子接口只会继承一个有冲突的抽象方法
    - 公有默认方法的冲突:子接口中必须重写一次有冲突的默认方法(注意要加default)
    - 公有静态方法和私有方法的冲突:
		不冲突,因为静态方法是直接属于接口的,只能使用本接口直接访问,而私有方法只能在接口中访问,也没有冲突

面试题:
     实现类重写接口中的默认方法,不需要加default
      子接口重写父接口中的默认方法,必须加default

知识点–3.7 实现类继承父类又实现接口时的冲突

目标

  • 实现类继承父类又实现接口时的冲突
父类和接口的公有静态常量的冲突
  • 子类无法继承有冲突的常量
class Fu{
    public static final int NUM1 = 10;
    public static final int NUM2 = 100;
}
interface A{
    public static final int NUM1 = 20;

}
class Zi extends Fu implements A{

}
public class Test {
    public static void main(String[] args) {
        /*
            公有静态常量的冲突:子类无法继承有冲突的常量
         */
        //System.out.println(Zi.NUM1);// 编译报错
        System.out.println(Zi.NUM2);

    }
}

父类和接口的抽象方法冲突
abstract class Fu{
    public abstract void method();
}
interface A{
    public abstract void method();
}
class Zi extends Fu implements A{
    @Override
    public void method() {
        System.out.println("Zi 重写有冲突的抽象方法");
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            公有抽象方法的冲突:子类必须重写一次有冲突的抽象方法
         */
        Zi zi = new Zi();
        zi.method();
    }
}
父类和接口的公有默认方法的冲突
  • 只会访问父类的
class Fu{
    public void method(){
        System.out.println("Fu 类中的默认方法method");
    }
}
interface A{
    public default void method(){
        System.out.println("A 接口中的默认方法method");
    }
}
class Zi extends Fu implements A{

}
public class Test {
    public static void main(String[] args) {
        /*
            公有默认方法的冲突:只会访问父类的
         */
        Zi zi = new Zi();
        zi.method();// Fu 类中的默认方法method
    }
}

父类和接口的公有静态方法
  • 只会访问父类的静态方法
class Fu{
    public static void method(){
        System.out.println("Fu 类中的静态方法method");
    }
}
interface A{
    public static void method(){
        System.out.println("A 接口中的静态方法method");
    }
}
class Zi extends Fu implements A{
    
}
public class Test {
    public static void main(String[] args) {
        /*
            公有静态方法的冲突:只会访问父类的静态方法
         */
        Zi.method();
    }
}

父类和接口的私有方法
  • 不存在冲突

小结

  实现类继承父类又实现接口时的冲突:
                - 公有静态常量的冲突:子类无法继承有冲突的常量
                - 公有抽象方法的冲突:子类必须重写一次有冲突的抽象方法
                - 公有默认方法的冲突:只会访问父类的
                - 公有静态方法的冲突:只会访问父类的静态方法
                - 私有方法的冲突: 不存在冲突

实操–3.8 抽象类和接口的练习

需求:

通过实例进行分析和代码演示抽象类和接口的用法。

1、举例:

​ 犬: —抽象父类

​ 行为:吼叫;吃饭;

​ 缉毒犬:继承犬类,实现缉毒接口

​ 行为:吼叫;吃饭;缉毒;

​ 缉毒接口:

​ 缉毒

  • 如果一个父类中的某个方法,所有子类都有不同的实现,那么该方法就应该定义成抽象方法,所以该父类就是抽象类 (父类一般都是抽象类)
  • 如果某个功能是一个类额外增加的,那么就可以把这个额外的功能定义到接口中,再这个类去实现

分析:

​ 由于犬分为很多种类,他们吼叫和吃饭的方式不一样,在描述的时候不能具体化,也就是吼叫和吃饭的行为不能明确。当描述行为时,行为的具体动作不能明确,这时,可以将这个行为写为抽象行为,那么这个类也就是抽象类。

​ 可是有的犬还有其他额外功能,而这个功能并不在这个事物的体系中 , 例如 : 缉毒犬。缉毒的这个功能有好多种动物都有 , 例如 : 缉毒猪 , 缉毒鼠。我们可以将这个额外功能定义接口中 ,让缉毒犬继承犬且实现缉毒接口 , 这样缉毒犬既具备犬科自身特点也有缉毒功能。

  • 额外的功能—> 在接口中定义,让实现类实现
  • 共性的功能—> 在父类中定义,让子类继承

实现:

// 抽象父类
public abstract class Dog {
    public abstract void houJiao();
    public abstract void eat();
}


public interface JiDu {
    public abstract void jiDu();
}


public class JiDuDog extends Dog implements JiDu{
    @Override
    public void houJiao() {
        System.out.println("缉毒犬找到了毒品,开始吼叫,汪汪汪....");
    }

    @Override
    public void eat() {
        System.out.println("缉毒之前,开始吃骨头...");
    }

    @Override
    public void jiDu() {
        System.out.println("吃完东西后,开始使用鼻子查找毒品....");
    }
}


public class Test {
    public static void main(String[] args) {
        // 创建缉毒狗对象
        JiDuDog jd = new JiDuDog();
        jd.eat();
        jd.jiDu();
        jd.houJiao();
    }
}

小结:

  • 额外的功能—> 在接口中定义,让实现类实现
    • 如果可以确定的通用功能,使用默认方法
    • 如果不能确定的功能,使用抽象方法
  • 共性的功能—> 在父类中定义,让子类继承
    • 如果可以确定的通用功能,使用默认方法
    • 如果不能确定的功能,使用抽象方法

第二章 多态

知识点-- 概述

目标:

  • 了解什么是多态,以及形成多态的条件

讲解:

引入

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

生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也是不一样的。可见,同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。

定义
  • 多态是指同一行为,对于不同的对象具有多个不同表现形式。
  • 程序中多态: 是指同一方法,对于不同的对象具有不同的实现.
前提条件【重点】
  1. 继承或者实现【二选一】
  2. 父类引用指向子类对象\接口引用指向实现类对象【格式体现】
  3. 方法的重写【意义体现:不重写,无意义】

小结:

  • 多态: 是指同一行为,对于不同的对象具有多个不同表现形式。
  • 条件:
    • 继承或者实现
    • 父类引用指向子类的对象\接口引用指向实现类对象
    • 方法的重写

知识点-- 实现多态

目标:

  • 如何实现多态

讲解:

多态的体现:父类的引用指向它的子类的对象

父类类型 变量名 = new 子类对象;
变量名.方法名();

父类类型:指子类对象继承的父类类型,或者实现的父接口类型。

class Animal{
    public void eat(){
        System.out.println("吃东西");
    }
}

class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }
}

class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼...");
    }
}

public class Test1 {
    public static void main(String[] args) {
        /*
            多态: 同一种行为,不同的事物具有不同的表现形态
            实现多态:
                1.继承或者实现
                2.父类引用指向子类对象\接口引用指向实现类对象
                3.方法重写
         */
        // 父类引用指向子类对象
        Animal anl = new Dog();// 多态
        anl.eat();// 狗吃骨头...

        Animal anl1 = new Cat();
        anl1.eat();// 猫吃鱼...
    }
}

小结:

  • 父类的引用指向子类的对象

知识点-- 多态时访问成员的特点

目标

  • 掌握多态时访问成员的特点

讲解:

  • 直接看演示代码:
class Animal{
    int num = 10;
    public void method1(){
        System.out.println("Animal 非静态method1方法");
    }
    public static void method2(){
        System.out.println("Animal 静态method2方法");
    }
}
class Dog extends Animal{
    int num = 20;

    public void method1(){
        System.out.println("Dog 非静态method1方法");
    }

    public static void method2(){
        System.out.println("Dog 静态method2方法");
    }
}

public class Test {
    public static void main(String[] args) {
        /*
            多态时访问成员的特点:
                成员变量:访问的是子类
                成员方法:
                    非静态方法:访问的是子类
                    静态方法: 访问的是父类
         */
        // 父类的引用指向子类的对象
        Animal anl = new Dog();
        System.out.println(anl.num);// 10

        anl.method1();// Dog 非静态method1方法

        anl.method2();// Animal 静态method2方法

    }
}

知识点-- 多态的形式

目标:

  • 多态的几种表现形式

讲解:

  • 多态的表现形式:

    • 普通父类多态

      public class Fu{}
      public class Zi extends Fu{}
      public class Demo{
          public static void main(String[] args){
              Fu f = new Zi();//左边是一个“父类”
          }
      }
      
      
    • 抽象父类多态

      public abstract class Fu{}
      public class Zi extends Fu{}
      public class Demo{
          public static void main(String[] args){
              Fu f = new Zi();//左边是一个“父类”
          }
      }
      
      
    • 父接口多态

    public interface A{}
    public class AImp implements A{}
    public class Demo{
        public static void main(String[] args){
            A a = new AImp();//左边是一个“接口”
        }
    }
    

知识点-- 多态的应用场景:

目标:

  • 掌握多态在开发中的应用场景

讲解:

多态的几种应用场景:

  • 变量多态 -----> 意义不大

    class Animal{
        public void eat(){
            System.out.println("吃东西...");
        }
    }
    class Dog extends Animal{
        @Override
        public void eat() {
            System.out.println("狗吃骨头");
        }
    }
    class Cat extends Animal{
        @Override
        public void eat() {
            System.out.println("猫吃鱼");
        }
    }
    public class Test {
        public static void main(String[] args) {
            // 变量多态: 父类类型的变量指向子类类型的对象
            // 如果变量的类型为父类类型,该变量就可以接收该父类类型的对象或者其所有子类对象
            Animal anl = new Dog();
            anl.eat();
    
            anl = new Cat();
            anl.eat();
        }
    }
    
    
  • 形参多态----> 常用

    class Animal{
        public void eat(){
            System.out.println("吃东西...");
        }
    }
    class Dog extends Animal{
        @Override
        public void eat() {
            System.out.println("狗吃骨头");
        }
    }
    class Cat extends Animal{
        @Override
        public void eat() {
            System.out.println("猫吃鱼");
        }
    }
    public class Test {
        public static void main(String[] args) {
            // 形参多态:参数类型为父类类型,该参数就可以接收该父类类型的对象或者其所有子类对象
            Dog d = new Dog();
            method(d);
    
            System.out.println("===============================");
    
            Cat c = new Cat();
            method(c);
        }
    
        // 需求: 定义一个方法,带有一个参数,该参数可以接收Animal类对象以及Animal类的所有子类对象
        // method(d); ====实参赋值给形参的时候==> Animal anl = new Dog();
        // method(c); ====实参赋值给形参的时候==> Animal anl = new Cat();
        public static void method(Animal anl){
            anl.eat();
        }
    
    }
    
    
  • 返回值多态—> 常用

    class Animal{
        public void eat(){
            System.out.println("吃东西...");
        }
    }
    class Dog extends Animal{
        @Override
        public void eat() {
            System.out.println("狗吃骨头");
        }
    }
    class Cat extends Animal{
        @Override
        public void eat() {
            System.out.println("猫吃鱼");
        }
    }
    public class Test {
        public static void main(String[] args) {
            // 返回值多态:如果返回值类型为父类类型,那么就可以返回该父类类型的对象或者其所有子类对象
            Animal anl = method();
            anl.eat();
        }
    
        public static Animal method(){
            //return new Animal();
            //return new Dog();
            return new Cat();
        }
    
        public static Animal method1(){
            if (1==1){
                // 条件1成立
                return new Animal();
            }else if (2==2){
                // 条件2成立
                return new Dog();
            }else{
                // 否则
                return new Cat();
            }
        }
    }
    
    

小结:

变量多态 -----> 意义不大:如果变量的类型为父类类型,该变量就可以接收该父类类型的对象或者其所有子类对象
形参多态----> 常用: 如果参数类型为父类类型,该参数就可以接收该父类类型的对象或者其所有子类对象
返回值多态---> 常用: 如果返回值类型为父类类型,那么就可以返回该父类类型的对象或者其所有子类对象

知识点-- 多态的好处和弊端

目标:

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

讲解:

  • 好处
    • 提高了代码的扩展性
  • 弊端
    • 多态的情况下,只能调用父类的共性内容,不能调用子类的特有内容。
  • 示例代码
class Animal{
    public void eat(){
        System.out.println("吃东西...");
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }

    // 特有的功能
    public void lookHome(){
        System.out.println("狗在看家...");
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            多态的好处和弊端:
                好处:提高代码的复用性
                弊端:无法访问子类独有的方法或者成员变量,因为多态成员访问的特点是,编译看父类
         */
        // 父类的引用指向子类的对象
        Animal anl = new Dog();
        anl.eat();
        //anl.lookHome();// 编译报错,因为多态成员访问的特点是,编译看父类,而父类中没有子类独有的功能
    }
}

小结:

多态的好处和弊端:
      好处:提高代码的复用性
      弊端:无法访问子类独有的方法或者成员变量,因为多态成员访问的特点是,编译看父类

知识点-- 引用类型转换

目标:

  • 向上转型与向下转型,instanceof关键字

讲解:

向上转型
  • 子类类型向父类类型向上转换的过程,这个过程是默认的。

     Aniaml anl = new Cat();  
    
向下转型
  • 父类类型向子类类型向下转换的过程,这个过程是强制的。

     Aniaml anl = new Cat();  
     Cat c = (Cat)anl;//向下转型
    
  • 示例代码

    class Animal{
        public void eat(){
            System.out.println("吃东西...");
        }
    }
    class Dog extends Animal{
        @Override
        public void eat() {
            System.out.println("狗吃骨头...");
        }
    
        // 特有的功能
        public void lookHome(){
            System.out.println("狗在看家...");
        }
    }
    class Cat extends Animal{
        @Override
        public void eat() {
            System.out.println("猫吃鱼...");
        }
    }
    
    class Person{}
    public class Test {
        public static void main(String[] args) {
            /*
                引用类型转换:
                    向上转型:子类类型向父类类型向上转换的过程,这个过程是默认\自动的。
                    向下转型:父类类型向子类类型向下转换的过程,这个过程是强制\手动的。
                            格式: 子类类型 对象名 = (子类类型)父类类型的变量;
                            注意:
                                1.向下转型的时候:右边父类类型的变量一定要指向要转型的子类类型的对象
                                2.不管是向上转型还是向下转型,一定满足父子类关系或者实现关系
             */
            // 向上转型:
            Animal anl = new Dog();
    
            // 向下转型:
            Dog dog = (Dog)anl;
    
            System.out.println("===================================");
            // 注意:右边父类类型的变量一定要指向要转型的子类类型的对象
            //Animal anl1 = new Animal();
            //Dog d1 = (Dog)anl1;// 运行报错,类型转换异常ClassCastException
    
    
            //Animal anl2 = new Cat();
            //Dog d2 = (Dog)anl2;// 运行报错,类型转换异常ClassCastException
    
            //Animal anl3 = new Person();// 编译报错,因为Animal和Person不是父子关系
            //Animal anl3 = (Animal) new Person();// 编译报错,因为Animal和Person不是父子关系
    
        }
    }
    
    
instanceof关键字
  • 向下强转有风险,最好在转换前做一个验证 :

  • 格式:

    变量名 instanceof 数据类型 
    如果变量属于该数据类型,返回true。
    如果变量不属于该数据类型,返回falseif( anl instanceof Cat){//判断anl是否能转换为Cat类型(anl是否是Cat类或Cat类的子类),如果可以返回:true,否则返回:false
        Cat c = (Cat)anl;//安全转换
    }
    
  • 示例代码

    class Animal{
        public void eat(){
            System.out.println("吃东西...");
        }
    }
    class Dog extends Animal{
        @Override
        public void eat() {
            System.out.println("狗吃骨头...");
        }
    
        // 特有的功能
        public void lookHome(){
            System.out.println("狗在看家...");
        }
    }
    class Cat extends Animal{
        @Override
        public void eat() {
            System.out.println("猫吃鱼...");
        }
    }
    public class Test {
        public static void main(String[] args) {
            /*
                instanceof关键字:
                    为什么要有instanceof关键字?
                        因为在引用类型转换的时候很容易出现类型转换异常,所以为了提高代码的严谨性,转型之前得先判断一下
                    怎么使用instanceof关键字判断呢?
                        if(变量名 instanceof 数据类型){
    
                        }
                     执行:
                        判断前面变量指向的对象类型是否是后面的数据类型:
                            如果前面变量指向的对象类型是属于后面的数据类型,那么就返回true
                            如果前面变量指向的对象类型不是属于后面的数据类型,那么就返回false
             */
            // 向上转型
            Animal anl = new Cat();
    
            // 向下转型
            //Dog  d = (Dog)anl;// 运行的时候会出现类型转换异常
            // 先判断,再转型
            if (anl instanceof Dog){
                Dog  d = (Dog)anl;
            }
    
            System.out.println("正常结束");
        }
    }
    
    

小结

 引用类型转换:
	向上转型:子类类型向父类类型向上转换的过程,这个过程是默认\自动的。
    向下转型:父类类型向子类类型向下转换的过程,这个过程是强制\手动的。
        格式: 子类类型 对象名 = (子类类型)父类类型的变量;
注意:
	1.向下转型的时候:右边父类类型的变量一定要指向要转型的子类类型的对象
    2.不管是向上转型还是向下转型,一定满足父子类关系或者实现关系

instanceof关键字:
	if(变量名 instanceof 数据类型){}
    如果变量属于该数据类型,返回true。
    如果变量不属于该数据类型,返回false

解决多态的弊端

class Animal{
    public void eat(){
        System.out.println("吃东西...");
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }

    // 特有的功能
    public void lookHome(){
        System.out.println("狗在看家...");
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            解决多态的弊端:
                弊端:无法访问子类独有的方法或者成员变量,因为多态成员访问的特点是,编译看父类
         */
        // 父类的引用指向子类的对象
        Animal anl = new Dog();// 向上转型
        anl.eat();// 狗吃骨头...

        //anl.lookHome();// 编译报错,因为多态成员访问的特点是,编译看父类,而父类中没有子类独有的功能

        // 先判断,后转型
        if (anl instanceof Dog){
            Dog d = (Dog)anl;// 向下转型
            d.lookHome();// 狗在看家...
        }

        System.out.println("正常结束");
    }
}

多态的应用场景综合案例

class Animal{
    public void eat(){
        System.out.println("吃东西...");
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }

    // 特有的功能
    public void lookHome(){
        System.out.println("狗在看家...");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼...");
    }
    // 特有的功能
    public void catchMouse(){
        System.out.println("猫抓老鼠...");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog d = new Dog();
        method(d);

        System.out.println("==========================");

        Cat c = new Cat();
        method(c);
    }

    // 形参多态: 如果父类类型作为方法的形参类型,那么就可以接收该父类类型的对象或者其所有子类的对象
    public static void method(Animal anl){
        anl.eat();
        //anl.lookHome();// 编译报错
        // anl.catchMouse();// 编译报错
        if (anl instanceof Dog){
            Dog d = (Dog)anl;// 向下转型 Dog类型
            d.lookHome();
        }

        if (anl instanceof Cat){
            Cat c = (Cat)anl;// 向下转型 Cat类型
            c.catchMouse();
        }

    }
}

第三章 内部类

知识点-- 内部类

目标:

  • 内部类的概述

讲解:

什么是内部类

将一个类A定义在另一个类B里面,里面的那个类A就称为**内部类,B则称为外部类**。

成员内部类
  • 成员内部类 :定义在类中方法外的类。

定义格式:

class 外部类 {
    class 内部类{

    }
}

在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car 中包含发动机类Engine ,这时,Engine 就可以使用内部类来描述,定义在成员位置。

代码举例:

class Car { //外部类
    class Engine { //内部类

    }
}
访问特点
  • 内部类可以直接访问外部类的成员,包括私有成员。
  • 外部类要访问内部类的成员,必须要建立内部类的对象。

创建内部类对象格式:

外部类名.内部类名 对象名 = new 外部类型().new 内部类型()

访问演示,代码如下:

// 外部类
public class Body {

    public void methodW1(){
        // 访问内部类的成员
        //Body.Heart bh = new Body().new Heart();
        Heart bh = new Heart();
        System.out.println(bh.numN);// 10
        bh.methodN1();// 内部类的成员方法 methodN1
    }

    // 成员变量
    private int numW = 100;

    // 成员方法
    private void methodW2(){
        System.out.println("外部类的成员方法 methodW2");
    }


    // 内部类
    public class Heart{
        // 成员变量
        int numN = 10;

        // 成员方法
        public void methodN1(){
            System.out.println("内部类的成员方法 methodN1");
        }

        public void methodN2(){
            // 访问外部类的成员
            System.out.println(numW);
            methodW2();
        }
    }


}


public class Test {
    public static void main(String[] args) {
        /*
            - 什么是内部类:将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,外面的那个B类则称为外部类。
            - 成员内部类的格式:
                 public class 外部类{
                     public class 内部类{

                    }
                 }
            - 成员内部类的访问特点:
                在其他类中,访问内部类的成员,得先创建内部类对象:
                    外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
                在外部类中,访问内部类的成员,得先创建内部类对象:
                    外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
                    内部类名 对象名 = new 内部类名();

                在内部类中,可以直接访问外部类的一切成员(包含私有的):

         */
        // 创建内部类的对象
        Body.Heart bh = new Body().new Heart();
        System.out.println(bh.numN);// 10
        bh.methodN1();// 内部类的成员方法 methodN1

        System.out.println("=======================");
        // 创建外部类对象
        Body b = new Body();
        b.methodW1();

        System.out.println("=======================");
        bh.methodN2();// 100    外部类的成员方法 methodW2

    }
}

小结:

内部类:将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
成员内部类的格式:
    public class 外部类名{
         public class 内部类名{

        }
    }
成员内部类的访问特点:
    - 内部类可以直接访问外部类的成员,包括私有成员。
    - 外部类要访问内部类的成员,必须要建立内部类的对象。

成员内部类的创建方式:
    外部类名.内部类名 对象名 = new 外部类名().new 内部类名();

知识点-- 匿名内部类

目标:

  • 匿名内部类

讲解:

概述
  • 匿名内部类 :是内部类的简化写法。它的本质是一个带具体实现的 父类或者父接口的 匿名的 子类对象
代码一
abstract class Animal{
    public abstract void eat();
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            匿名内部类:
                概述:本质其实就是一个类的匿名子类的对象
                作用:就是用来简化代码的,没有其他的功能
                格式:
                    new 类名(){
                        实现抽象方法
                    };
         */
        // 需求:调用Animal类的eat方法
        // 1.创建一个子类继承Animal类
        // 2.在子类中重写eat抽象方法
        // 3.创建子类对象
        // 4.使用子类对象调用eat方法
        Dog d = new Dog();// 创建Animal子类对象
        d.eat();// d---->是Animal类的子类的对象
        // 问题:以上4步一步都不能少,有点麻烦,是否可以简化代码?
        // 解决:匿名内部类可以简化代码,因为它可以不创建子类的情况下,直接得到一个类的子类对象

        System.out.println("==========================");
        // 创建Animal子类对象<=====>Animal类的匿名内部类
        // 父类的引用指向子类的对象
        Animal anl = new Animal() {
            @Override
            public void eat() {
                System.out.println("匿名内部类");
            }
        };// 是Animal类的子类的对象
        anl.eat();
    }
}

代码二
interface A{
    public abstract void show();
}
class Imp implements A{
    public void show(){
        System.out.println("实现类实现show方法");
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            匿名内部类:
                概述:本质是一个接口的匿名实现类的对象
                格式:
                    new 接口名(){
                        实现抽象方法
                    };
         */
        // 需求:调用A接口的show方法
        // 1.创建实现类实现A接口
        // 2.在实现类中重写show方法
        // 3.创建实现类对象
        // 4.使用实现类对象调用show方法
        Imp imp = new Imp();// imp就是接口的实现类的对象
        imp.show();

        System.out.println("==============================");
        // 简化: 匿名内部类
        A a = new A() {
            @Override
            public void show() {
                System.out.println("匿名内部类");
            }
        };
        a.show();
    }
}

小结

对于类:
	概述:本质其实就是一个类的匿名子类的对象
    格式:
        new 类名(){
            实现抽象方法
        };
对于接口:
	概述:本质是一个接口的匿名实现类的对象
    格式:
        new 接口名(){
            实现抽象方法
        };
匿名内部类作用:就是用来简化代码的,没有其他的功能
使用场景:
	如果方法的形参类型为抽象类或者接口类型,那么为了简化代码,可以直接传入该抽象类或者接口的匿名内部类
  • 补充

      // 匿名子类的匿名对象
            new Imp().show();// 实现类的匿名对象调用show方法
            new A() {
                @Override
                public void show() {
                    System.out.println("匿名内部类");
                }
            }.show();// 匿名实现类的匿名对象调用show方法
    

第四章 引用类型使用小结

目标

​ 实际的开发中,引用类型的使用非常重要,也是非常普遍的。我们可以在理解基本类型的使用方式基础上,进一步去掌握引用类型的使用方式。基本类型可以作为成员变量、作为方法的参数、作为方法的返回值,那么当然引用类型也是可以的。在这我们使用两个例子 , 来学习一下。

讲解

6.1 类名作为方法参数和返回值
class Person{
    public String name;
    public int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void show(){
        System.out.println(name+","+age);
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            类名作为方法参数和返回值:
         */
        // 创建Person
        Person p = new Person("冰冰",18);
        method1(p);
        System.out.println("=========================================");
        // 调用method2;
        Person person = method2(p);
        person.show();// 冰冰,20
    }

    // 类作为方法的参数类型
    public static void method1(Person p){
        p.show();// 冰冰,18
    }

    // 类作为方法的参数类型和返回值类型
    public static Person method2(Person p){
        p.age = 20;// 把age改为20
        return p;
    }
}

6.2 抽象类作为方法参数和返回值
  • 抽象类作为形参:表示可以接收任何此抽象类的"子类对象"作为实参;
  • 抽象类作为返回值:表示"此方法可以返回此抽象类的任何子类对象";
abstract class Animal{
    public abstract void eat();
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }
}
public class Test {
    public static void main(String[] args) {
        // 调用method1,就得传入Animal抽象类的子类对象
        method1(new Dog());

        System.out.println("========================");
        // 调用method1,就得传入Animal抽象类的子类对象
        method1(new Animal() {
            @Override
            public void eat() {
                System.out.println("匿名内部类的方式...");
            }
        });

        System.out.println("========================");
        // 调用method2方法,会返回一个Animal类的子类对象
        //Animal anl = method2();
        Dog d = (Dog)method2();
    }

    // 抽象类作为方法参数类型
    public static void method1(Animal anl){
        anl.eat();
    }

    // 抽象类作为方法返回值类型
    public static Animal method2(){
        return new Dog();
    }
}

6.3 接口作为方法参数和返回值
  • 接口作为方法的形参:【同抽象类】
  • 接口作为方法的返回值:【同抽象类】
interface A{
    void show();
}
class Imp implements A{
    public void show(){
        System.out.println("实现类的方式实现show方法");
    }
}
public class Test {
    public static void main(String[] args) {
        // 接口作为方法参数和返回值
        // 调用method1方法,就得传入A接口的实现类对象
        method1(new Imp());

        System.out.println("===================");

        // 调用method1方法,就得传入A接口的匿名内部类
        method1(new A() {
            @Override
            public void show() {
                System.out.println("匿名内部类的方式实现show方法");
            }
        });

        System.out.println("===================");

        // 调用method2方法,就会返回A接口的实现类对象
        //A a = method2();
        Imp imp = (Imp) method2();


    }

    // 接口作为方法参数
    public static void method1(A a){
        a.show();
    }

    // 接口作为方法返回值
    public static A method2(){
        return new Imp();
    }
}

6.4 类名作为成员变量

​ 我们每个人(Person)都有一个身份证(IDCard) , 为了表示这种关系 , 就需要在Person中定义一个IDCard的成员变量。定义Person类时,代码如下:

class Person {
    String name;//姓名
    int age;//年龄
}

​ 使用String 类型表示姓名 , int 类型表示年龄。其实,String本身就是引用类型,我们往往忽略了它是引用类型。如果我们继续丰富这个类的定义,给Person 增加身份证号 , 身份证签发机关等属性,我们将如何编写呢?这时候就需要编写一个IDCard类了

修改Person类:

class Person{
    String name;// 引用数据类型定义成员变量  String类
    int age;// 基本类型定义成员变量
    IdCard idCard;

    public Person(String name, int age, IdCard idCard) {
        this.name = name;
        this.age = age;
        this.idCard = idCard;
    }
    // ...
}
class IdCard{
    String idNum;// 身份证号码
    String address;// 地址

    public IdCard(String idNum, String address) {
        this.idNum = idNum;
        this.address = address;
    }
    // ....
}
public class Test {
    public static void main(String[] args) {
        // 创建IdCard对象
        IdCard idCard = new IdCard("440330200010101919","广东省深圳市宝安区公安局");
        // 创建Person对象
        Person p = new Person("张三",18,idCard);
        System.out.println(p.name+","+p.age+","+p.idCard.idNum+","+p.idCard.address);// java支持链式编程
    }
}

类作为成员变量时,对它进行赋值的操作,实际上,是赋给它该类的一个对象。同理 , 接口也是如此 , 例如我们笔记本案例中使用usb设备。在此我们只是通过小例子 , 让大家熟识下引用类型的用法 , 后续在咱们的就业班学习中 , 这种方式会使用的很多。

6.5 抽象类作为成员变量
  • 抽象类作为成员变量——为此成员变量赋值时,可以是任何它的子类对象
abstract class Pet{
    String name;

    public Pet(String name) {
        this.name = name;
    }
}
class Dog extends Pet{

    public Dog(String name) {
        super(name);
    }
}
class Person{
    String name;
    int age;
    Pet pet;

    public Person(String name, int age, Pet pet) {
        this.name = name;
        this.age = age;
        this.pet = pet;
    }
}
public class Test {
    public static void main(String[] args) {
        // 抽象类作为成员变量:传入抽象类的子类对象
        Pet pet = new Dog("旺财");
        Person p = new Person("张三",18,pet);
        System.out.println(p.name);
        System.out.println(p.age);
        System.out.println(p.pet.name);

    }
}

6.6 接口作为成员变量
  • 接口类型作为成员变量——【同抽象类】
abstract interface Pet{

}
class Dog implements Pet{


}
class Person{
    String name;
    int age;
    Pet pet;

    public Person(String name, int age, Pet pet) {
        this.name = name;
        this.age = age;
        this.pet = pet;
    }
}
public class Test {
    public static void main(String[] args) {
        // 接口作为成员变量:传入接口的实现类对象
        Pet pet = new Dog();
        Person p = new Person("张三",18,pet);
        System.out.println(p.name);
        System.out.println(p.age);
        System.out.println(p.pet);

    }
}

英雄: name,皮肤,法术(接口)

小结

  	  - 类名作为方法参数和返回值:可以直接传入该类的对象;返回该类的对象
      - 抽象类作为方法参数和返回值:只能传入该类的子类对象;返回该类的子类对象
      - 接口作为方法参数和返回值:只能传入该接口的实现类对象;返回该接口的实现类对象
          传递的都是地址值,返回的也是地址值
          
      - 类作为成员变量    : 赋该类的对象
      - 抽象类作为成员变量 ; 赋该类的子类对象
      - 接口作为成员变量   : 赋该接口的实现类对象
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Java中的接口是一种抽象的数据类型,它定义了类应该具有的方法和属性,但并不提供实现细节。它可以被看作是一种规范,让开发者知道他们需要实现的方法和属性。 接口可以被类实现,类实现接口时必须实现接口中定义的所有方法和属性。这种实现方式使得类可以具有多个接口的特性,从而实现了Java中的多重继承。 下面是一个简单的接口示例: ```java public interface Animal { void move(); void eat(String food); } ``` 上面的接口定义了两个方法`move()`和`eat(String food)`,类实现这个接口时必须实现这两个方法。 接口还可以继承其他接口,从而扩展接口的功能。下面是一个继承其他接口接口示例: ```java public interface Bird extends Animal { void fly(); } ``` 上面的接口继承了Animal接口,同时添加了一个新的方法`fly()`。 接口还可以用于回调函数的实现,例如定义一个接口作为事件监听器,当某个事件发生时,回调函数会调用接口中定义的方法。 接口Java中非常重要的概念,对于理解Java多态和抽象类等概念有很大的帮助。 ### 回答2: Java继承和多态是面向对象编程中的重要概念,而接口Java语言中实现多态的方式之一。 继承是指一个类可以继承另一个类的属性和方法。通过使用关键字“extends”,子类可以继承父类的属性和方法,并且可以在子类中添加新的方法或属性。继承可以实现代码的重用,同时也体现了面向对象的特点。 多态是指同一个类型的对象在不同的情况下表现出不同的行为。在Java中,多态可以通过接口来实现。接口是一个抽象类的特殊形式,它定义了一组方法的签名,但没有实现这些方法的具体逻辑。一个类可以实现一个或多个接口,并实现接口中定义的所有方法。通过接口,我们可以将不同的类组织在一起,以实现类之间的松耦合和代码的重用。 接口定义了一组规范,而类则去实现这些规范。接口可以通过关键字“implements”来实现。通过实现接口,类必须实现接口中定义的所有方法。接口可以作为方法的参数类型或返回值类型,从而实现多态的效果。 总之,学习Java继承和多态接口,我们能够更好地组织和管理代码,实现代码的重用和灵活性。接口的使用使得我们可以面向接口编程,而不是面向具体的类,从而提高了代码的可扩展性和可维护性。掌握这些概念,能够更有效地编写面向对象的Java程序。 ### 回答3: 在Java编程语言中,继承和多态是重要的概念,而其中的接口是实现多态的关键。接口是一种约定或契约,是一组方法的集合,但没有具体的实现。接口定义了一些必须实现的方法,而这些方法的具体实现则由实现接口的类来完成。 通过继承和实现接口,我们能够实现代码的重用和灵活性。继承允许一个类继承另一个类的属性和方法,而接口则定义了一组方法,使得不同的类能够被视为同一类型,从而实现多态接口有两个主要的作用:规范和实现多态。通过接口的规范,我们可以对各个类的方法进行统一管理和调用。这样一来,我们能够降低代码的重复性,改进代码的可读性和维护性。通过实现多态,我们可以让一个对象以不同的形态呈现,从而实现灵活性和扩展性。 在Java中,一个类可以实现一个或多个接口。通过实现接口,类必须实现接口中定义的所有方法。这样一来,我们可以根据接口的类型来引用不同的对象,而不需要关心具体实现的细节。 例如,我们有一个接口叫做Animal,定义了一个方法叫做move()。然后,我们有两个类,一个是Dog,一个是Cat,它们都实现了Animal接口。通过多态性,我们可以使用Animal类型的引用来引用Dog和Cat对象,然后调用move()方法,而不用担心具体是哪个类的对象。 总之,学习Java的继承和多态接口是非常重要和有用的。接口能够帮助我们实现代码的重用、灵活性和扩展性。通过继承和实现接口,我们能够更好地组织和管理代码,提高代码的可读性和维护性,从而更高效地进行程序开发

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

潮浪之巅

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

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

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

打赏作者

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

抵扣说明:

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

余额充值