JavaSE进阶5之内部类

内部类

  • 内部类就是定义在一个类里面的类,里面的类可以理解成(寄生),外部类可以理解为(宿主)
public class People{
	public class Heart{
	}
}

内部类的使用场景、作用

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

内部类的分类

  1. 静态内部类
  2. 成员内部类(非静态内部类)
  3. 局部内部类
  4. 匿名内部类

静态内部类

  • 有static修饰,属于外部类本身
  • 它的特点和使用与普通类是完全一样的,类有的成分它都有,只是位置在别人里面而已
public class Outer{
	public static class Inner{}
}

静态内部类创建对象的格式
格式:外部类名.内部类名 对象名=new 外部类名.内部类名

 Outer.Inner in=new Outer.Inner();

静态内部类可以直接访问外部类的静态成员,但是不能直接访问外部类的实例成员,外部类的实例成员必须用外部类对象访问

public class Person {
    private String trait;
    public static String school="父母";

    public void eat(){
        System.out.println("人是铁饭是钢");
    }

    public static class Inner{
        private String name;
        private int age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public static String header="头部";

        public Inner(){
            System.out.println("内部类的无参数构造器");
        }
        public Inner(String name,int age){
            this.name=name;
            this.age=age;
            System.out.println(this.name+this.age+"\t\t内部类的有参数构造器");
        }

        public void show(){
            System.out.println("Person.Inner的show方法");
            System.out.println(name+age);
            //System.out.println(trait); 静态内部类不可以访问外部类的实例成员
            //eat();
            System.out.println("school:"+school);  //静态内部类可以访问外部类的静态成员
        }
    }
}
public class Test {
    public static void main(String[] args) {
        Person.Inner a=new Person.Inner();
        a.setName("张三");
        a.setAge(15);
        a.show();
        System.out.println("内部类的静态成员:"+Person.Inner.header);

        Person.Inner b=new Person.Inner("李四",20);
        b.show();
    }
}

请添加图片描述

成员内部类

  • 无static修饰,属于外部类的对象
  • JDK16之前,成员内部类不能定义静态成员,JDk16开始也可以定义静态成员了
public class Outer{
	public class Inner{
	}
}

成员内部类创建对象的格式:
格式: 外部类名.内部类名 对象名=new 外部类构造器.new 内部类构造器

Outer.Inner in=new Outer().new Inner();

成员内部类可以直接访问外部类的静态成员,外部类的静态成员只有一份可以共享访问
成员内部类的实例方法可以直接访问外部类的实例成员,因为必须先有外部类对象,才能有成员内部类对象,所以可以直接访问外部类对象的实例成员

public class Animal {
    private String name;

    public static String hobby="吃饭";

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

    public Animal() {
    }

    public class Dog{
        private int age;
        public void show(){
            System.out.println("Animal名字叫:"+name+age+"能"+hobby);
        }

        public String getName() {
            return name;
        }

        public void setName(String dogName) {
            name = dogName;
        }

        public Dog(int age) {
            this.age = age;
        }

        public Dog(){
            System.out.println("内部类的无参数构造器");
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

    }
}

public class demo {
    public static void main(String[] args) {
        Animal.Dog a=new Animal().new Dog();
        a.setName("笨笨");
        a.setAge(2);
        a.show();
        System.out.println("---------------");
        Animal.Dog b=new Animal("奇奇").new Dog(2);
        b.show();
        System.out.println("Animal.hobby:"+Animal.hobby);
    }
}

请添加图片描述
请添加图片描述

在成员内部类中访问所在外部类对象,格式:外部类名.this

public 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
        }
    }
}

class demo1{
    public static void main(String[] args) {
        People.Heart p=new People().new Heart();
        p.show();
    }
}

请添加图片描述

局部内部类

  • 局部内部类放在方法、代码块、构造器等执行体中
  • 局部内部类的类文件名:外部类$N内部类.class
public class Demo1 {
    public static void main(String[] args) {
        //局部内部类
        class Dog{
            private String name;
            private int age;

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public int getAge() {
                return age;
            }

            public void setAge(int age) {
                this.age = age;
            }

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

            public Dog() {
            }

            @Override
            public String toString() {
                return "Dog{" +
                        "name='" + name + '\'' +
                        ", age=" + age +
                        '}';
            }
        }


        Dog d=new Dog();
        d.setName("笨笨");
        d.setAge(2);
        System.out.println(d.toString());

        Dog d1=new Dog("奇奇",2);
        System.out.println(d1.toString());
    }
}

请添加图片描述

匿名内部类

  • 本质上是一个没有名字的局部内部类,定义在方法中,代码块中,等
  • 作用:方便创建子类对象,最终目的为了简化代码编写。
    格式
new|抽象类名|或者接口名(){
	重写方法;
}
Employee a=new Employee(){
	public void work(){
	}
};
a.work();

特点总结:

  1. 匿名内部类是一个没有名字的内部类
  2. 匿名内部类写出来就会产生一个匿名内部类的对象
  3. 匿名内部类的对象类型相当于是当前new的那个类型的子类类型
abstract class Animal{
    public abstract void run();
}

interface Person{
    public void eat();
}
public class demo {
    public static void main(String[] args) {
//        Animal a = new Tiger();  多态
//        a.run();

        Animal b=new Animal(){
            @Override
            public void run() {
                System.out.println("老虎跑的贼快~");
            }
        };
        b.run();

        Person c=new Person(){
            @Override
            public void eat() {
                System.out.println("女的要吃饭");
            }
        };
        c.eat();
    }
}

//class Tiger extends Animal{
//    @Override
//    public void run() {
//        System.out.println("老虎跑的真快~");
//    }
//}

请添加图片描述

匿名内部类常见使用形式

  • 某个学校需要让老师,学生,运动员一起参加游泳比赛
public class demo01 {
    public static void main(String[] args) {
        goSwimming(new Swimming(){
            @Override
            public void swim() {
                System.out.println("老师游的比较快");
            }
        });

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

        goSwimming(new Swimming(){
            @Override
            public void swim() {
                System.out.println("学生游得很快");
            }
        });

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

        goSwimming(new Swimming() {
            @Override
            public void swim() {
                System.out.println("运动员游得最快");
            }
        });
    }

    public static void goSwimming(Swimming swimming){
        System.out.println("开始");
        swimming.swim();
        System.out.println("结束");
    }
}

请添加图片描述

匿名内部类真实使用场景

  • 给按钮绑定点击事件
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;

public class demo02 {
    public static void main(String[] args) {
        JFrame win=new JFrame("登录界面");
        Panel panel=new Panel();
        win.add(panel);

        JButton btn=new JButton("登录");
        panel.add(btn);
        //匿名内部类 实现接口AbstractAction
        btn.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(win,"登录成功!");
            }
        });

        //展示页面
        win.setSize(400,300);
        win.setLocationRelativeTo(null);
        win.setVisible(true);
    }
}

请添加图片描述
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值