# 面向对象进阶

# 面向对象的三特

  • 封装性、继承性、多态性

# static 静态关键字

  • static 表示静态,是一种java中的一种修饰符,可以修饰成员方法、成员变量

# 被static修饰的成员变量,称为静态变量,静态变量

# 特点

  • 被该类所有对象共享
  • 不属于对象,属于类
  • 随着类的加载而加载,优先于对象的存在

    注意

    被static修饰的静态成员,属于该类公共成员,属于使用该类创建的对象共有的属性

# 调用方式

  • 类名调用(推荐)
  • 对象名调用 (静态成员随着类的加载而加载,因此不推荐对象名调用)
public class Static {
    public static void main(String[] args) {
        Student.schoolName = "尚硅谷";
        Student s1 = new Student("张三", 18);
        s1.show();//学校: 尚硅谷姓名:张三年龄:18
        Student s2 = new Student("李四", 19);
        s2.show();//学校: 尚硅谷姓名:李四年龄:19


        //更改类中静态成员
        Student.schoolName = "黑马大学";
        s1.show();//学校: 黑马大学姓名:张三年龄:18
        s2.show();//学校: 黑马大学姓名:李四年龄:19
    }
}

# 被static修饰的成员方法,称为静态方法

# 特点

  • 多用在测试类和工具类当中
  • JavaBean当中很少会用

# 调用方式

  • 类名调用(推荐)
  • 对象名调用

# static关键字注意事项

# 工具类

帮我们做一些事情,但是不描述任何事物的类

# JavaBean类

用来描述一些事物的类。比如Student、Teacher、Dog、Cat等

# 测试类

用来检查其他类是否书写正确,带有main方法的类,是程序的主入口

# 工具类

不是用来描述一些事物的,而是帮我们做一些事情的类

# 工具类书写注意事项

  • 私有化构造方法 (防止外部创建对象),创建工具类对象是无意义的
  • 工具类中的成员变量,尽量设置为私有(static)的,外界直接使用类名调用成员方法

# 例 定义数组工具类

public class ArrayUtils {
    //私有化构造方法
    private ArrayUtils() {
    }

    //编写静态方法

    //返回整数数组的内容
    //只考虑整数数组
    //只考虑一维数组
    public static String printArr(int[] arr) {
        if (arr.length == 0) return "[]";
        StringJoiner sj = new StringJoiner(",", "[", "]");
        for (int j : arr) sj.add(String.valueOf(j));
        return sj.toString();
    }


    //用于返回平均分
    //只考虑浮点型数组
    //只考虑一维数组
    public static double getAerage(double[] arr) {
        double sum = 0;
        for (double j : arr) sum += j;
        return sum / arr.length;
    }
}

# main方法

  • main方法,是程序的主入口
  • public被JVM虚拟机调用,访问权限足够大
  • static被JVM虚拟机调用,不用创建对象,直接类名访问
  • 因为main方法是静态的,所以测试类中的其他方法也需要是静态的
  • void被JVM虚拟机调用,因此不需要给虚拟机返回值
  • main一个通用名称。虽然不是关键字,但是被JVM识别
  • String[] args以前用于键盘接收数据,现在没用

# 继承

  • 继承是多态的前提,如果没有继承就没有多态
  • 继承是面向对象编程中一个重要的概念,它允许我们定义一个类,继承另一个类,从而获得另一个类的属性和方法。

# 继承的好处

  • 可以把多个子类中重复代码抽取到父类中,提高代码的复用性
  • 子类可以在父类的基础上,增加其他功能,使子类更加强大

# 什么时候使用继承

当类与类之间,存在相同共性的内容,并满足子类是父类中的一种,就可以考虑继承,来优化代码

# 继承的特点

  • Java只支持单继承,不支持多继承,但支持多层继承
  • 单继承: 一个子类只能继承一个父类

# 子类能继承父类的哪些内容

# 构造方法 不能被继承

# 成员变量 可以被继承

  • 所有成员变量都可以被继承
  • 使用private私有关键字修饰的成员变量,不能直接使用,需使用父类getset方法进行访问

# 成员方法

  • 如果该方法能够被添加到虚方法表当中,则该方法可以被继承
  • 虚方法表:非private修饰的成员方法、非static修饰的成员方法、非final修饰的成员方法

# 继承中成员的访问特点

  • 如果父类和子类有同名的成员,变量以就近原则进行访问
  • this:表示当前对象,可以访问该类中的成员
  • super:表示父类,可以访问父类中的成员
public class Fu() {
    String name = "Fu";
}

public class Zi() extends Fu {
    String name = "Zi";

    public void show() {
        String name = "Zi show";
        System.out.println(name);//Zi show
        System.out.println(this.name);//Zi
        System.out.println(super.name);//Fu
    }
}

# 继承体系练习

  1. 现有四种动物:布偶猫、中国狸花猫、哈士奇、泰迪
  2. 暂时不考虑属性,只考虑行为 请按照继承的思想特点进行继承思想体系设计
    四种动物有以下行为
  • 布偶猫:吃饭、喝水、抓老鼠
  • 中国狸花猫:吃饭、喝水、抓老鼠
  • 哈士奇:吃饭、喝水、看家、拆家
  • 泰迪:吃饭、喝水、看家、蹭一蹭

# 方法重写

在继承中,当父类的方法不能满足子类现有的需求时,需要进行方法重写

# 书写格式

在继承体系中,子类出现了和父类中一模一样的方法声明,我们就称子类这个方法是重写的方法

# @Override重写注解

  • @Override是放在重写的方法上,校验子类重写时语法是否正确
  • 加上注解后如果有红色波浪线,表示语法错误
  • 建议重写方法都加@Override注解,代码安全、优雅
public class hashDog extends dog {
    //方法重写
    @Override
    public void doSomething2() {
        System.out.println(this.name + "拆家");
    }
}

# 重写方法的注意事项

  • 重写方法的名称、形参列表必须与父类中的一致
  • 子类重写父类方法时,访问权限子类必须大于等于父类
  • 子类重写父类方法时,返回值类型子类必须小于等于父类
  • 重写的方法尽量和父类保持一致
  • 只有被添加到虚方法表中的方法 才能被重写

# 继承中构造方法的访问特点

  • 子类不能继承父类的构造方法,但是可以通过super关键字调用
  • 子类构造方法的第一行,有一个默认的super()
  • 默认先访问父类中无参构造方法,再执行自己
  • 如果想要方法访问有参构造,必须手动书写
public class Person {
    String name;
    int age;

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

public class Student extends Person {
    public Student(String name, int age) {
        //访问有参构造
        super(name, age);
    }
}

# 多态

# 什么是多态?

对象的多种形态

# 多态的前提

  • 有继承/实现关系
  • 有父类引用指向子类对象
  • 有方法的重写

# 多态的好处

  • 使用父类型作为参数,可以接受所有子类对象
  • 体现多态的拓展性与便利
public class main {
    public static void main(String[] args) {
        Person p = new Person("张三", 18);
        someOne(p);
        Student s = new Student("李四", 19);
        someOne(s);
        Admin a = new Admin("王五", 20);
        someOne(a);
    }

    //这个方法既能接收Student类,Admin类
    //只能把类型写为这两个类型的父类
    public static void someOne(Person p) {
        p.show();
    }
}

# 多态的弊端

  • 多态性无法访问子类特有的成员
  • 如需访问子类特有成员需使用类型转换(自动类型转换,强制类型转换)
  • 自动类型转换 Person p = new Student();
  • 强制类型转换 Student s = (Student) p;

# 多态调用特点

  • 在成员变量中,使用多态方式创建的成员,只能访问父类成员
  • 在成员方法中,使用多态方式创建的成员,不可以访问子类特有成员(父类没有子类有)
public class main {
    public static void main(String[] args) {
        //使用多态创建对象
        Person1 p = new Admin1();
        //使用多态调用成员变量
        //编译看左边,运行看左边
        //只能访问父类成员变量
        System.out.println(p.name);//张三
        //使用多态创建对象调用成员方法
        //编译看左边,运行看右边
        //在进行编译的时候先进行类型检查,检查不通过则报错
        p.show();

        //多态的弊端
        //不能调用子类的特有功能(父类没有,子类有)
        // p.hobby(); //报错
        //解决方法 让父类型变为子类
        //转换时类型不能瞎转 子类是什么类型就转为什么类型

        //方法1 强制类型转换
//        Admin1 a = (Admin1) p;
//        a.hobby();
        //方法2 类型判断转换
        if (p instanceof Admin1 a1) {
            a1.hobby();
        } else if (p instanceof Teacher t1) {
            t1.todo();
        }
    }


}

class Person1 {
    String name = "张三";

    public void show() {
        System.out.println("我是" + name);
    }
}

class Admin1 extends Person1 {
    String name = "李四";

    @Override
    public void show() {
        System.out.println("我是------" + name);
    }

    public void hobby() {
        System.out.println("我是管理员,我的爱好是打篮球");
    }
}

class Teacher extends Person1 {
    String name = "王五";

    @Override
    public void show() {
        System.out.println("我是]]']]]]" + name);
    }

    public void todo() {
        System.out.println("我是老师,我正在教书");
    }
}

# 强制类型转换能解决什么问题

  • 可以转换为真正的子类类型,从而调用子类特有的功能
  • 转换类型与真实对象类型不一致会报错
  • 转换的时候用instanceof判断类型是否一致
//测试类
public class text {
    public static void main(String[] args) {
        Person4 p = new Person4("张三", 18);
        //年龄为18岁的张三养了一只旺财,它今年3岁了
        //3岁的狗两只前腿死死的抱住骨头猛吃
        //3岁的旺财看家
        p.keepPet(new Dog("旺财", 3), "骨头");

//        年龄为18岁的张三养了一只招财猫,它今年2岁了
//        2岁的猫眯着眼睛吃鱼
//        2岁的招财猫抓老鼠
        p.keepPet(new Cat("招财猫", 2), "鱼");
    }
}

//动物父类
class Animal {
    String name;
    int age;

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

    public void eat(String food) {
        System.out.println(age + "岁的" + name + "吃" + food);
    }
}

//子类狗
class Dog extends Animal {
    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat(String food) {
        System.out.println(age + "岁的狗两只前腿死死的抱住" + food + "猛吃");
    }

    public void lookHome() {
        System.out.println(age + "岁的" + name + "看家");
    }
}

//子类猫
class Cat extends Animal {
    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat(String food) {
        System.out.println(age + "岁的猫眯着眼睛吃" + food);
    }

    public void catchMouse() {
        System.out.println(age + "岁的" + name + "抓老鼠");
    }
}

//饲养员
class Person4 {
    String name;
    int age;

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

    //喂养狗
//    public void keepPet(Dog dog) {
//        System.out.println("年龄为" + age + "岁的" + name + "养了一只" + dog.name + ",它今年" + dog.age + "岁了");
//        dog.eat("骨头");
//    }
//
//    //喂养猫
//    public void keepPet(Cat cat) {
//        System.out.println("年龄为" + age + "岁的" + name + "养了一只" + cat.name + ",它今年" + cat.age + "岁了");
//        cat.eat("鱼");
//    }
    public void keepPet(Animal animal, String food) {
        System.out.println("年龄为" + age + "岁的" + name + "养了一只" + animal.name + ",它今年" + animal.age + "岁了");
        //在此种情况下animal调用不了子类中特有的方法
        animal.eat(food);
        //使用类型判断强制转换类型
        if (animal instanceof Dog dog) dog.lookHome();
        else if (animal instanceof Cat cat) cat.catchMouse();
    }
}

#

# 什么是包

包就是文件夹,用来管理各种不同功能的Java类,方便后期代码维护

# 包的命名规则

  • 需要全部英文小写,见名知意

# 使用其他类时的导包规则

  • 使用同一个包中的类时,不需要导包
  • 使用Java.lang包中的类时,不需要导包
  • 其他情况都需要导包
  • 如果同时使用两个包中的同名类,需要用全类名(包名+类名)
import java.util.Scanner;
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //全类名
        main.util.Scanner sc1 = new main.util.Scanner(System.in);
    }
}

# final关键字

  • final关键字可以用于变量、方法、类
  • 变量:叫做常量,只能赋值一次,不能修改
  • 方法:表示该方法是最终方法,不能被重写
  • 类:表示该类是最终类,不能被继承

    注意

    在使用final关键字修饰变量时,需要遵守以下规则

    1. 如果是基本数据类型,则该变量必须被初始化,并且不能被修改
    2. 如果是引用数据类型,则该变量存储的地址值不能发生改变,对象内部可以改变

:::

# 权限修饰符

权限修饰符:是用来控制一个成员能够被访问的范围
可以修饰成员变量、方法、构造方法、内部类

# 权限修饰符的分类

public>protected>default(空着不写)>private

  • public:公共权限,任何类都可以访问
  • private:私有权限,只有自己可以访问
修饰符 同一个类中 同一个包中其他类 不同包下的子类 不同包下的无关类
public Y Y Y Y
protected Y Y Y
default Y Y
private Y

# 代码块

# 代码块的分类

  • 静态代码块:静态代码块在类加载的时候执行,只执行一次
  • 局部代码: 局部代码块在方法执行时执行,每次执行方法都会执行一次
  • 构造代码块:构造代码块在构造方法执行时执行,每次执行构造方法都会执行一次

# 构造代码块

抽取构造方法中的重复代码(但写法不够灵活)

# 静态代码块

数据初始化时,静态代码块只执行一次

public class Main {
    static {
        System.out.println("静态代码块执行");
    }

    public static void main(String[] args) {
    }
}

# 抽象类和抽象方法

# 抽象类

  • 抽象类不能被实例化,只能被继承
  • 抽象类中可以定义抽象方法,也可以定义非抽象方法
  • 具有抽象方法的类必须是抽象类
  • 抽象类中可以有构造方法
  • 抽象类的子类要么重写抽象类中的所有抽象方法要么是抽象类

# 抽象方法

  • 抽象方法没有方法体,只有方法名
  • 抽象方法必须定义在抽象类中
  • 抽象方法必须被重写,重写时必须使用@Override注解
  • 抽象方法不能被私有化
public class text {
    public static void main(String[] args) {
        Frog f = new Frog("小青蛙", 1);
        f.toDo();
        Sheep s = new Sheep("小羊", 2);
        s.toDo();
    }
}

//具有抽象方法的类必须是抽象类
abstract class Animal {
    String name;
    int age;

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

    public void drink() {
        System.out.print("喝水");
    }

    public abstract void toDo();
}

class Frog extends Animal {
    public Frog(String name, int age) {
        super(name, age);
    }

    @Override
    public void toDo() {
        super.drink();
        System.out.println("吃虫子");
    }
}

class Sheep extends Animal {
    public Sheep(String name, int age) {
        super(name, age);
    }

    @Override
    public void toDo() {
        super.drink();
        System.out.println("吃草");
    }
}

# 接口

接口是用来约束一个类的,接口当中的成员都是抽象的,接口当中的成员都是公共的

# 接口当中成员的特点

# 成员变量

  • 只能是常量
  • 默认修饰符:public static final

# 构造方法

没有

# 成员方法

  • 只能是抽象方法
  • 默认修饰符:public abstract
  • jdk7以前:接口中只能定义抽象方法

# 接口跟类之间的关系

# 类和类之间的关系

继承关系,只能单继承,不能多继承,但是可以多层继承

# 类和接口的关系

实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口

# 接口和接口的关系

继承关系i可以单继承也可以多继承

public class textSport {
    public static void main(String[] args) {
        //创建篮球教练
        BasketballCoach basketballCoach = new BasketballCoach("张三", 30, "篮球");
        basketballCoach.teach();
        //创建乒乓球教练
        TennisCoach tennisCoach = new TennisCoach("李四", 40, "乒乓球");
        tennisCoach.teach();
        tennisCoach.speak();
        //创建乒乓球运动员
        TennisPlear tennisPlear = new TennisPlear("王五", 20, "乒乓球");
        tennisPlear.study();
        tennisPlear.speak();
        //创建篮球运动员
        BasketballPlear basketballPlear = new BasketballPlear("赵六", 25, "篮球");
        basketballPlear.study();
    }
}

//人员
class Person {
    String name;
    int age;

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

//教练
class Coach extends Person {
    String teamName;

    public Coach(String name, int age, String teamName) {
        super(name, age);
        this.teamName = teamName;
    }

    public void teach() {
        System.out.println(name + "教" + teamName);
    }


}

//运动员
class Plear extends Person {
    String teamName;

    public Plear(String name, int age, String teamName) {
        super(name, age);
        this.teamName = teamName;
    }

    public void study() {
        System.out.println(name + "学" + teamName);
    }
}

//篮球教练
class BasketballCoach extends Coach {
    public BasketballCoach(String name, int age, String teamName) {
        super(name, age, teamName);
    }
}

//乒乓球教练
class TennisCoach extends Coach implements speakEn {
    public TennisCoach(String name, int age, String teamName) {
        super(name, age, teamName);
    }

    @Override
    public void speak() {
        System.out.println(name + "说英语");
    }
}

//篮球运动员
class BasketballPlear extends Plear {
    public BasketballPlear(String name, int age, String teamName) {
        super(name, age, teamName);
    }
}

//乒乓球运动员
class TennisPlear extends Plear implements speakEn {
    public TennisPlear(String name, int age, String teamName) {
        super(name, age, teamName);
    }

    @Override
    public void speak() {
        System.out.println(name + "说英语");
    }
}

# Jdk8以后接口中新增的方法

# 允许在接口中定义默认方法,需要使用关键字default修饰

作用:解决接口升级问题

# 接口中默认方法的定义格式

  • 格式:public default 返回值类型 方法名(参数列表){方法体}
  • 举例:public default void method(){System.out.println("123")

# 接口中默认方法的注意事项

  • 默认方法不是抽象方法,所以不强制被重写,但是如果被重写,重写的时候去掉default关键字
  • public可以省略,但不可以省略default
  • 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写

public interface inter {
    //接口中的默认方法,可以重写也可以不重写
    public default void show() {
        System.out.println("我是默认方法----");
    }
}

# 允许在接口中定义静态方法,需要使用关键字static修饰

# 接口中静态方法的定义格式

  • 格式:public static 返回值类型 方法名(参数列表){方法体}
  • 举例:public static void method(){System.out.println("静态方法");}

    注意

    静态方法只能通过接口名调用,不能通过实现类名或者对象名调用 public可以省略,但不可以省略static

# jdk9以后接口中新增的私有方法

使用private修饰可以

# 接口中私有方法的定义格式

  • 格式:private 返回值类型 方法名(参数列表){方法体}

  • 举例:private void method(){System.out.println("私有方法");}

  • 格式2:private static 返回值类型 方法名(参数列表){方法体}

  • 举例2:private static void method(){System.out.println("私有静态方法");}

注意

如果方法是静态方法,那么私有方法必须是静态的,静态私有方法是给静态方法服务的

//接口中的私有方法
public interface interA {
    public default void method1() {
        System.out.println("默认方法1");
        //调用接口中的私有方法
        method3();
    }

    public default void method2() {
        System.out.println("默认方法2");
        //调用接口中的私有方法
        method3();
    }

    //提取接口中公共部分 组成一个私有方法
    private void method3() {
        System.out.println("这里有100行代码");
    }
}

# 接口总结

  • 接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了
  • 当一个方法的参数是接口时,可以传递接口所有的实现类对象,这种方式称之为接口的多态

# 适配器模式

  • 当一个接口中抽象方法过多,但是但是我只要使用其中一部分的时候,就可以使用适配器设计模式

# 书写步骤

  1. 编写中间类XXXadapter,实现对应的接口
  2. 对接口中的抽象方法空实现
  3. 让真正的实现类继承中间类,并重写需要用的方法
  4. 为避免其他类创建适配器的对象,中间的适配器类用abstract修饰
//适配器设计模式
public interface interB {
    public void method1();

    public void method2();

    public void method3();

    public void method4();

    public void method5();
}

abstract class interBadapter implements interB {

    @Override
    public void method1() {

    }

    @Override
    public void method2() {

    }

    @Override
    public void method3() {

    }

    @Override
    public void method4() {

    }

    @Override
    public void method5() {

    }
}

class classB extends interBadapter {
    public void method1() {
        System.out.println("重写方法");
    }
}

# 内部类

# 类的五大成员

属性、方法、构造方法、代码块、内部类

# 什么是内部类

  • 在一个类的里面再定义一个类,那么这个类就叫做内部类
  • 内部类表示的是外部类的一部分
  • 内部类单独出现没有意义

# 内部类的访问特点

  • 内部类可以直接访问外部类的成员,包括私有
  • 外部类要访问内部类的成员,必须创建对象
class classB extends interBadapter {
    public void classB() {
        //外部类要想访问内部类必须创建对象
        classB1 b1 = new classB1();
        b1.show();
    }

    public void method1() {
        System.out.println("重写方法");
    }

    //内部类
    class classB1 {
        String name;
        int age;

        public void show() {
            System.out.println("内部类的定义");
        }
    }
}

# 内部类的分类

  • 成员内部类
  • 局部内部类
  • 静态内部类
  • 匿名内部类(重点掌握)

# 成员内部类

  • 写在成员位置的,属于外部类成员
  • 成员内部类可以被一些修饰符所修饰,比如private、默认、protectedpublicstatic

修饰符权限

  1. 默认权限 只能在本包中使用
  2. private私有 只能在成员内部使用
  3. protected受保护的 只能在本包和子类中使用
  4. public公共的 可以在任何地方使用
  5. static静态 只能在静态内部类中使用
public class main {
    public static void main(String[] args) {
        //方法一 直接创建成员内部类的对象
        OutSide.InSide inside = new OutSide().new InSide();
        //方法二 在外部类中使用函数导出成员内部类
        Object inside1 = new OutSide().getInSide();
    }
}

class OutSide {
    String name;

    class InSide {
        String age;
    }

    //向外导出成员内部类的对象
    public InSide getInSide() {
        return new InSide();
    }
}

# 成员内部类变量的获取


class OutSide {
    number a = 10;

    class InSide {
        number a = 20;

        public void show() {
            number a = 30;
            System.out.println(a);//30
            //this表示内部类对象
            System.out.println(this.a);//20
            //OutSide.this表示成员内部类所创建的对象
            System.out.println(OutSide.this.a);//10
        }
    }
}

# 静态内部类

  • 写在成员位置的,属于外部类成员
  • static修饰,只能访问外部类的静态成员的内部类被称为静态内部类
  • 如果想要访问非静态的需要创建对象

创建静态内部类对象的格式

  1. 外部类名.内部类名 对象名 = new 外部类名.内部类名(); 调用静态方法格式
  2. 外部类名.内部类名.静态方法名();
public class main {
    public static void main(String[] args) {
        //创建静态内部类对象
        OutSide.InSide inSide = new OutSide.InSide();
        //调用静态方法
        OutSide.InSide.getInSide();
    }
}

class OutSide {
    String name;

    static class InSide {
        static String age;

        //向外导出成员内部类的对象
        static void getInSide() {
            //  System.out.println(age);//静态只能访问静态
            System.out.println("内部类成员访问");
        }

        public void getInSide2() {
            System.out.println(age);
        }
    }
}

# 局部内部类

  • 将内部类定义在方法里面就叫局部内部类,类似于方法里面的局部变量
  • 外界是无法直接使用,需要在方法内部直接创建对象并使用
  • 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
public class main {
    public static void main(String[] args) {
        OutSide2 outSide2 = new OutSide2();
        outSide2.showMed();
    }
}


//局部内部类
class OutSide2 {
    public void showMed() {
        //写在方法中的内部类被称为局部内部类
        class InSide {
            int age = 10;

            public void getInSide() {
                System.out.println("局部内部类方法被调用了");
            }
        }
        InSide inSide = new InSide();
        System.out.println(inSide.age);
        inSide.getInSide();
    }
}

# 匿名内部类

  • 隐藏了名字的内部类,可以写在成员位置,也可以写在局部位置
  • 匿名内部类格式:new 类名或接口名(){重写方法}

# 格式细节

  • 包含了继承或实现,方法重写,创建对象
  • 整体就是一个类的子类对象或者接口的实现类对象

# 使用场景

当方法的参数是接口或者类时,以接口为例可以传递这个接口的实现类对象,如果实现类只要使用一次,就可以使用匿名内部类简化代码

public class main {
    public static void main(String[] args) {
//继承匿名内部类
        new OutSide2() {
            //继承需实现父类中所有的实现方法
            @Override
            public void showMed1() {
                System.out.println("showMed1");
            }
        };
        //接口匿名内部类
        new textInter() {
            //实现接口中的方法
            @Override
            public void show() {
                System.out.println("show");
            }
        };
        //传递接口或实现类的对象简化代码
        show(new textInter() {
            @Override
            public void show() {
                System.out.println("传递接口或实现类的对象简化代码");
            }
        });//传递接口或实现类的对象简化代码
    }

    public static void show(textInter a) {
        a.show();
    }
}

abstract class OutSide2 {
    public abstract void showMed1();
}

上次更新: 9/9/2025, 8:40:32 PM