[Java]面向对象-内部类

类的五大成员:属性、方法、构造方法、代码块、内部类

内部类

在一个类里边再定义一个类。可以在外部其他类中创建内部类对象并调用它的方法

public class Outer {//外部类
    public class inner{//内部类

    }
}
内部类使用时机: 
  • 内部类表示的事物是外部类的一部分
  • 内部类单独出来没有任何意义
特点:

1.内部类可以直接访问外部类的成员,包括私有

2.外部类要访问内部类的成员必须创建对象

package day15.demo10;

public class Car {
    String carname;
    int age;
    String color;

    class engine{
        String name;
        int age;

        public void show(){
            System.out.println(name);
            System.out.println(carname);
        }
    }
    engine engine = new engine();
    public void show(){
        System.out.println(carname);
        System.out.println(engine.name);
    }
}

 内部类分类

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类
成员内部类:

写在成员位置的,属于外部类的成员

可以被权限修饰符修饰

类定义在了成员位置 (类中方法外称为成员位置,无static修饰的内部类)

使用方法:

 外部类.内部类。 // 访问内部类的类型都是用 外部类.内部类

获取成员内部类对象:

法一:在外部类中编写方法,对外提供内部类对象

public class Outer {
    String outername;
    private class Inner{
        String innername = null;
    }
    public Inner getinstance(){
        return new Inner();
    }
}
===========================================================================================
public class main {
    public static void main(String[] args) {
//        Outer.Inner inner = new Outer().new Inner();
//        inner.innername = "hello";
//        System.out.println(inner.innername);
        Outer outer = new Outer();
        outer.getinstance();
        System.out.println(outer.getinstance());
    }
}

法二:直接创建格式:外部类.内部类 对象名 = 外部类对象.内部类对象

public class main {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().new Inner();
        inner.innername = "hello";

        System.out.println(inner.innername);
    }
}

内部类访问外部类的成员变量 

public class Outer {
    private int a = 10;
    
    class Inner{
        private int a = 20;

        public void show(){
            int a = 30;
            System.out.println(a);
            System.out.println(this.a);
            System.out.println(Outer.this.a);
        }
    }
}

为什么是Outer.this.a?

通过Java内存分析工具我们可以看到,内部类Inner中隐含一个Outer.this来记录外部类的地址值,当内部类访问外部类的成员变量的时候会通过内部类隐含的Outer.this来访问Outer类进而访问其成员变量。

 可以看到,内部类和外部类是两个不同的类,通过Outer.this来记录内部类外部类的关系

静态内部类: 

成员内部类被static修饰时就称为静态内部类

静态内部类只能访问外部类中的静态变量和静态方法,如果要想访问非静态的需要创建对象

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

调用非静态方法的格式:先创建对象,用对象调用

调用静态方法格式:外部类.内部类.方法名();

public class Outer {
    int a = 10;
    static int b = 20;
    static class Inner{
        public void show1(){
            Outer outer = new Outer();
            System.out.println(outer.a);
            System.out.println(b);
            System.out.println("show1");
        }

        public static void show2(){
            System.out.println("show2");
        }
    }
}
==========================================================================================
public class main {
    public static void main(String[] args) {
        Outer.Inner o = new Outer.Inner();
        o.show1();
        Outer.Inner.show2();//调用静态方法
    }
}
局部内部类: 

1.将内部类定义在方法内就叫做局部内部类,类似于方法里边的局部变量

2.外界无法直接使用,需要在方法内部创建对象并调用

3.该类可以直接访问外部类的成员,也可以直接访问方法内的局部变量

 注 : 不能用权限修饰符修饰

public class Outer {
    int b = 20;
    public void show(){
        int a = 10;
        class Inner{//局部内部类
            String name;
            int age;

            public void method(){
                System.out.println(b);
                System.out.println("Inner");
            }

            public void method2(){
                System.out.println("Inner static");
            }
        }

        Inner inner = new Inner();
        System.out.println(inner.name);
        System.out.println(inner.age);
        inner.method();
        inner.method2();
    }
}
匿名内部类: 

匿名内部类本质上就是隐藏了名字的内部类,是内部类的简化写法

格式:

new 类名或者接口名() {
     重写方法;
};

包含了:

  • 继承或者实现关系

  • 方法重写

  • 创建对象

public interface swim {
    void swim();
}
===========================================================================================
public class main {
    public static void main(String[] args) {
        new swim(){

            @Override
            public void swim() {
                System.out.println("swim");
            }
        };
    }
}

绿色的框表示的是没有名字的对象,new是用来创建此类。类实现了swim接口实现的重写 。

如果swim是类的话,就是继承关系,匿名内部类继承了名为swim的抽象类

 main$1为编译生成的匿名内部类字节码文件,可以通过Javap进行反编译字节码文件,可以看到匿名内部类与接口之间的实现关系或者和类之间的继承关系

使用时机:

一个类在只使用一次时,在使用一个类时需要再创建一个类太麻烦了,此时使用匿名内部类的形式简化代码。当将匿名内部类调用的接口赋值给一个对象时候,此时就形成了接口的多态。

package day15.demo15;

public class main {
    public static void main(String[] args) {
        new swim(){

            @Override
            public void swim() {
                System.out.println("swim");
            }
        }.swim();


//        new Outer() {
//            @Override
//            public void eat() {
//
//            }
//        };
//        dog dog = new dog();
//        method(dog);传统方法

        method(//匿名内部类形式 多态
                new Outer() {
                    @Override
                    public void eat() {
                        System.out.println("狗吃屎");
                    }
                }
        );
    }
    public static void method(Outer a){
        a.eat();
    }
}
注意事项:
  1. 匿名内部类是隐藏了名字的类,可以写在成员位置,也可以写在局部位置
  2. 匿名内部类包含了继承或实现,方法重写,创建对象。 整体就是一个类的子类对象或者接口实现类的对象
  3. 当一个方法的参数是接口或者类时,以接口为例,可以传递这个接口的实现类对象,如果实现类只需要使用一次,就可以用匿名内部类简化代码。
Java是一种非常流行的面向对象编程语言,它的核心概念之一就是类与对象。 类是用来描述具有相同属性和行为的一组对象的模板。可以把类看作是一种自定义的数据类型。在类中,我们可以定义各种属性和方法来描述对象的特征和行为。属性是对象的状态,而方法则是对象的行为。 对象是类的具体实例化,在内存中占有一定的空间。可以把对象看作是类的变量,通过实例化类来创建对象。对象可以访问类中定义的属性和方法,并且每个对象都有自己独立的状态。 通过类和对象的组合使用,我们可以实现面向对象编程的核心思想:封装、继承和多态。 封装是指将数据和操作数据的方法封装在类的内部,隐藏内部实现细节,只提供公共的访问方法。这样可以保证数据的安全性和一致性,提高代码的可维护性和重用性。 继承是指通过已有的类创建新的类,提供新类所具有的属性和方法,并且可以重写或扩展父类的方法。继承可以减少代码的冗余,提高代码的复用性和可扩展性。 多态是指同一类型的对象在调用同一个方法时,可以有不同的行为表现。它通过方法重载和方法重写实现。多态可以提高代码的灵活性和扩展性,让我们能够编写更加通用和可复用的代码。 总之,类与对象是Java面向对象编程的基石,它们的灵活组合使用可以让我们编写出高质量、模块化的代码,并且提高了代码的可维护性和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值