面向对象学习27 - 内部类
内部类
成员内部类是什么? 如何创建其对象?
就是类中的一个普通成员,类似前面我们学过的普通成员变量、成员方法
外部类名。内部类名 对象名 = new 外部类 (...).new 内部类 (...);
成员内部类的实例方法中,访问其他成员有啥特点?
可以直接访问外部类的实例成员、静态成员
可以拿到当前外部类对象,格式是:外部类名.this。
代码示例
package com.itheima.innerclass;
public class Outer {
    public static String schoolName = "黑马程序员";
    private int age; 
    public static void test() {
        System.out.println("test()");
    }
    // 成员内部类:无 static 修饰,属于外部类的对象特有
    public class Inner {
        private String name;
        // 无参构造器
        public Inner() {
            System.out.println("Inner() name = " + name);
        }
        // 有参数构造器
        public Inner(String name) {
            this.name = name;
            System.out.println("Inner(String name)");
        }
        public void show() {
            System.out.println("show");
            // 访问外部类静态成员
            System.out.println(schoolName);
            // 访问外部类静态方法
            test();
            // 访问外部类实例成员
            System.out.println(age);
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
}
package com.itheima.innerclass;
public class InnerClassDemo1 {
    public static void main(String[] args) {
        // 演示 Outer 类的成员内部类 Inner 的创建与使用
        Outer.Inner oi = new Outer().new Inner();
        oi.setName("王麻子");
        oi.show();
        // 成员内部类访问外部成员的特点(拓展)演示 
        // 1、成员内部类中访问外部类成员(略,已在 Inner 类 show 方法体现)
        // 2、成员内部类的实例方法中,拿到当前外部类对象:外部类名.this
        People.Heart heart = new People().new Heart();
        heart.show();
    }
    // 演示“外部类名.this”的 People 类,含成员内部类 Heart
    static class People {
        private int heartBeat = 100;
        public class Heart {
            private int heartBeat = 80;
            public void show() {
                int heartBeat = 200;
                // 访问局部变量
                System.out.println(heartBeat); // 200  
                // 访问内部类 Heart 的成员变量
                System.out.println(this.heartBeat); // 80  
                // 访问外部类 People 的成员变量(通过 外部类名.this 语法)
                System.out.println(People.this.heartBeat); // 100  
            }
        }
    }
}
代码说明
Outer 类:定义了静态成员 schoolName、test 方法,实例成员 age,以及成员内部类 Inner。Inner 类可直接访问外部类的静态成员、静态方法和实例成员。
InnerClassDemo1 类:main 方法中演示了两种成员内部类用法:
直接创建并使用 Outer 类的成员内部类 Inner,调用其方法验证对外部类成员的访问。
通过 People 类及其成员内部类 Heart,演示 外部类名.this 语法,用于在内部类中精准访问外部类的成员变量(区分局部变量、内部类成员变量、外部类成员变量)。
运行逻辑:执行 main 方法时,先创建 Outer.Inner 对象并调用 show,再创建 People.Heart 对象并调用 show,观察控制台输出即可验证成员内部类对外部类成员的访问规则 。
静态内部类
有static修饰的内部类
声明格式为:外部类名.内部类名 对象名 = new 外部类.内部类(...);
可以直接访问外部类的静态成员,不能直接访问外部类的实例成员
代码示例
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Outer{
    public static String schoolName;
    private int age;//实例成员
    //静态内部类:属于外部类本身持有
    public static class Inner{
        private String name;
    public void show(){
        System.out.println(schoolName);
        //静态内部类中是否可以直接访问外部类的静态成员? 可以!
        System.out.println(age);//报错
        //静态内部类中是否可以直接访问外部类的实例成员? 不可以。
    }
}
public class InnerClassDemo2 {
    public static void main(String[] args){
        Outer.Inner inner - new Outer.Inner();
        inner.show();
    }
}
匿名内部类
1、匿名内部类的书写格式是什么样的?
new 类或接口(参数值...){
类体(一般是方法重写);
};
举例:
new Animal(){
    @Override
    public void cry(){
    }
};
2、匿名内部类的特点?
匿名内部类本质上是一个子类,会立刻创建出一个子类对象


3、匿名内部类的基本作用?
可以更方便的创建出一个子类对象。
代码示例
public abstract class Animal{
    public abstract void cry();
}
public class Test{
    public static void main(String[] args){
        Animal a = new Animal(){
            @Override
            public void cry(){
                System.out.println("🐱猫会喵喵喵的叫~")
            }
        };
        a.cry();//🐱猫会喵喵喵的叫~
    }
}
匿名内部类代码展示
//老师学生游泳比赛
interface Swim{
    void swimming();//游泳方法
}
//传统方案使用实现类对接口进行实现
class Teacher implements Swim{
    public void swimming(){
        System.out.println("老师🏊狗爬式游泳~~~");
    }
}
class Student implements Swim{
    public void swimming(){
        System.out.println("学生🏊自由式游泳~~~");
    }
}
//使用匿名实现类对接口进行实现
public class swimTest{
    // 声明 start 方法
    public static void start(Swim swimmer) {
        System.out.println("比赛开始!");
        swimmer.swimming();
        System.out.println("比赛结束!");
    }
    public static void main(String[] args){
        Swim s1 = new Swim(){
            @Override
            public void swimming(){
                System.out.println("学生🏊贼快");
            }
        };
        start(s1);
        System.out.println("============================================");
        Swim s2 = new Swim(){
            @Override 
            public void swimming(){
                System.out.println("老师🏊贼溜");
            }
        };
        start(s2);
    }
}
//学生列表排序
package com.itheima.innerclass3;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    // 姓名 年龄 身高 性别
    private String name;
    private int age;
    private double height;
    private char sex;
}
import java.util.Arrays;
// 注意:如果使用的是 IDEA 等开发工具,需确认已正确安装并启用 Lombok 插件,否则可能编译报错
public class Test4 {
    public static void main(String[] args) {
        // 目标:完成给数组排序,理解其中匿名内部类的用法。
        // 准备一个学生类型的数组,存放 6 个学生对象。
        Student[] students = new Student[6];
        students[0] = new Student("殷素素", 35, 171.5, '女');
        students[1] = new Student("杨幂", 28, 168.5, '女');
        students[2] = new Student("张无忌", 25, 181.5, '男');
        students[3] = new Student("小昭", 19, 165.5, '女');
        students[4] = new Student("赵敏", 27, 167.5, '女');
        students[5] = new Student("刘亦菲", 36, 168, '女');
        @Override
        public int compare(Student o1, Student o2) {
            // 指定排序规则:
            // 如果你认为左边对象 大于 右边对象 那么返回正整数。
            // 如果你认为左边对象 小于 右边对象 那么返回负整数。
            // 如果两边相等那么返回0。
        return o1.getAge() - o2.getAge(); // 按照年龄升序! 
        }
        // 遍历数组中的学生对象并输出
        for (int i = 0; i < students.length; i++) {
            Student s = students[i];
            System.out.println(s);
        }
    }
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号