【JAVA】多态、内部类

1 多态

多态:同类型的对象,执行同一个行为,会表现出不同的行为特征

优势

  • 右边对象可以实现随意更改,更改后续业务只需改右边对象,其它代码无需更改,便于扩展和维护
  • 定义方法时,使用父类型作为参数,该方法就可以接受这父类的一切子类对象

劣势:多态下不能使用子类的独有功能

常见形态

java 复制代码
父类类型 对象名=new 子类构造器;
接口 对象名 = new 实现类构造器;
java 复制代码
// 一般形态
Dog a = new Dog();
a.run()

Tortoise t= new Tortoise();
t.run();

// 多态(Dog和Tortoise都继承父类Animal)
Animal a = new Dog();
a.run()

Animal t= new Tortoise();
t.run();

多态中成员访问特点

|------|----------------------------------------------------|
| 方法调用 | 编译看左边(run方法在写代码时写的是Animal方法),运行看右边(运行的时候运行Dog里的方法) |
| 变量调用 | 编译看左边,运行也看左边(运行的时候变量值还是父类变量的值)。(多态侧重行为多态) |

强制类型转换

有继承关系/实现的两个类型就可以强制转换

作用:可以解决多态下的劣势,实现调用子类独有的功能

java 复制代码
Animal a = new Dog();
a.run()
// 强制类型转换
Tortoise t = (Tortoise) a;
t.layEggs();

Animal t2 = new Tortoise();
Dog d = (Dog)t;//会出现异常

若转型后的类型与对象的真是类型不是同一个类型,会出现异常ClassCastException

解决办法:强制类型转换前用instanceof判断当前对象的真是类型,再转换

java 复制代码
// 变量是否为真是类型,是返回true
变量名 instanceof 真实类型

2 内部类

内部类是定义在类里面的类

java 复制代码
public class People{
    public class Student{
    }
}

使用场景、作用

  • 当一个事物的内部,还有一部分需要一个完整的结构进行描述,这个完整的结构只外部事物用,那么这个内部的完整结构就可以选择使用内部类来设计
  • 内部类通常可以方便访问外部类的成员,包括私有成员
  • 内部类提供了更好的封装性,内部类本身可以用private,protected等修饰,封装性可以做更多的控制

静态内部类

有static修饰,属于外部类本身,它的特点和使用与普通类完全一样,类中有的成分也都具备,只是位置在类里面

java 复制代码
public class People{
    // 静态成员内部类
    public static class Student{
    }
}

// 静态内部类创建对象格式
People.Student s = new People.Student();
  • 静态内部类可以直接访问外部类的静态成员,因为外部类的静态成员只有一份,可以共享
  • 静态内部类不可以直接访问外部类的实例成员,因为外部类的实例成员必须外部类成员访问

成员内部类

无static修饰,属于外部类的对象,JDK16开始成员内部类可以定义静态成员

java 复制代码
public class Outer{
    public class Inner{
    }
}

// 成员内部类创建对象格式
Outer.Inner in = new Outer().new Inner();
  • 成员内部类可以直接访问外部类的静态成员,因为外部静态成员只有一份可以被共享访问
  • 成员内部类的实例方法可以直接访问外部类的实例成员方法,因为必须现有外部类对象,才能有成员内部类对象,所以可以直接访问外部类对象的实例成员

若为了使用方便,定义为静态内部类;若希望访问外部类的所有成员,则定义为成员内部类

java 复制代码
class People{
    private int heartbeat = 150;
    public class Heart{
        private int heartbeat = 110;
        public void show(){
            int heartbeat = 78;
            System.out.println(heartbeat); // 78
            System.out.println(this.heartbeat); // 110
            System.out.println(People.this.heartbeat); // 150
        }
    }
}

局部内部类

局部内部类放在方法、代码块、构造器等执行体中。

java 复制代码
public class Test {
    static {
        //在代码块中定义
        class C{
        }
    }
    public static void main(String[] args) {
        class A{
            private String name;
            public static int num = 100; // JDK 16开始支持。
            public void show() {
            }
        }
        A a = new A();
        a.show();
    }
    
    public static void test(){
        // 定义在普通方法中
        class B{

        }
    }
}

匿名内部类*

本质上是一个没有名字的局部内部类,定义在方法、代码块等中

作用:方便创建子类对象,最终目的是为了简化代码编写

特点:匿名内部类没有名字,写出来会产生一个匿名内部类的对象。匿名内部类的对象类型相当于是当前new的那个类型的子类类型

java 复制代码
public class Test1 {
    public static void main(String[] args) {
        // 匿名内部类的形式(Animal是抽象类不能调用,不用再创建子类了)
        Animal a = new Animal(){
            @Override
            public void run() {
                System.out.println("动物动物跑");
            }
        };
        a.run();
    }
}

abstract class Animal{
    public abstract void run();
}
相关推荐
坊钰21 分钟前
【Java 数据结构】移除链表元素
java·开发语言·数据结构·学习·链表
chenziang126 分钟前
leetcode hot100 LRU缓存
java·开发语言
会说法语的猪32 分钟前
springboot实现图片上传、下载功能
java·spring boot·后端
码农老起33 分钟前
IntelliJ IDEA 基本使用教程及Spring Boot项目搭建实战
java·ide·intellij-idea
m0_7482398337 分钟前
基于web的音乐网站(Java+SpringBoot+Mysql)
java·前端·spring boot
时雨h41 分钟前
RuoYi-ue前端分离版部署流程
java·开发语言·前端
麒麟而非淇淋1 小时前
Day13 苍穹外卖项目 工作台功能实现、Apache POI、导出数据到Excel表格
java
云计算DevOps-韩老师1 小时前
【网络云计算】2024第52周-每日【2024/12/25】小测-理论&实操-自己构造场景,写5个系统管理的脚本-解析
开发语言·网络·云计算·bash·perl
暮色尽染1 小时前
Python 正则表达式
开发语言·python