【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();
}
相关推荐
网安INF5 分钟前
RSA加密算法:非对称密码学的基石
java·开发语言·密码学
明月*清风5 分钟前
c++ —— 内存管理
开发语言·c++
蔡蓝10 分钟前
设计模式-观察着模式
java·开发语言·设计模式
异常君23 分钟前
@Bean 在@Configuration 中和普通类中的本质区别
java·spring·面试
jackson凌23 分钟前
【Java学习笔记】Math方法
java·笔记·学习
西北大程序猿1 小时前
单例模式与锁(死锁)
linux·开发语言·c++·单例模式
你不是我我1 小时前
【Java开发日记】说一说 SpringBoot 中 CommandLineRunner
java·开发语言·spring boot
yuan199971 小时前
Spring Boot 启动流程及配置类解析原理
java·spring boot·后端
2301_807606431 小时前
Java——抽象、接口(黑马个人听课笔记)
java·笔记