Java的编程之旅33——内部类

1.内部类

内部类就是在一个类中定义另一个类,这个类中被定义的类就叫做内部类

内部类定义格式

public class 类名{

        修饰符 class 内部类名{

                成员...

        }

}

代码中的体现

public class Outer {
    private String strOuter= "这是外部类中的私有成员变量";
    public void OuterMethod(){
        System.out.println("这是外部类中的公有成员函数");
    }

    //定义内部类
    public class Inner{
        private String strInner = "这是内部类中的私有成员变量";
        public void InnerMethod(){
            System.out.println("这是内部类中的私有成员方法");
        }
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        System.out.println(outer.strOuter);
        outer.OuterMethod();
    }
}

这段代码定义了一个外部类Outer和一个内部类Inner。

在外部类Outer中,定义了一个私有成员变量strOuter和一个公有成员函数OuterMethod。strOuter是外部类中的私有成员变量,只能在外部类中直接访问。OuterMethod是外部类中的公有成员函数,可以在外部类和外部类的对象中访问和调用。

内部类Inner是定义在外部类Outer中的,可以直接访问外部类的成员变量和方法。内部类Inner的定义和普通类一样,它有一个私有成员变量strInner和一个公有成员函数InnerMethod。

在main函数中,首先创建了一个Outer类的对象outer,然后通过outer对象访问了外部类的私有成员变量strOuter和公有成员函数OuterMethod。

要访问内部类Inner的成员变量和方法,需要创建内部类的对象。由于内部类是非静态的,所以需要通过外部类的对象来创建内部类的对象。这段代码没有创建内部类Inner的对象,所以没有访问内部类的成员变量和方法。

那么接下来,我们想办法调用一下内部类,可以这么做:

public class Outer {
    private String strOuter= "这是外部类中的私有成员变量";
    public void OuterMethod(){
        System.out.println("这是外部类中的公有成员函数");
    }

    //定义内部类
    public class Inner{
        private String strInner = "这是内部类中的私有成员变量";
        public void InnerMethod(){
            System.out.println("这是内部类中的私有成员方法");
        }
    }

    public void runInner(){
        Inner inner = new Inner();
        System.out.println(inner.strInner);
        inner.InnerMethod();
    }


    public static void main(String[] args) {
        Outer outer = new Outer();
        System.out.println(outer.strOuter);
        outer.OuterMethod();
        //通过外部类调用runInner方法
        outer.runInner();
    }
}

Outer类中定义了一个名为runInner的方法,该方法在其内部创建了一个Inner对象inner,并使用inner.strInnerinner.InnerMethod()来访问内部类的成员变量和方法。

最后,我们通过outer.runInner()来调用runInner方法,间接地通过外部类对象来访问内部类的成员变量和方法。

还可以使用多重调用关系,创建一个内部类对象来调用内部类

public class Outer {
    private String strOuter= "这是外部类中的私有成员变量";
    public void OuterMethod(){
        System.out.println("这是外部类中的公有成员函数");
    }

    //定义内部类
    public class Inner{
        private String strInner = "这是内部类中的私有成员变量";
        public void InnerMethod(){
            System.out.println("这是内部类中的私有成员方法");
        }
    }

    public void runInner(){
        Inner inner = new Inner();
        System.out.println(inner.strInner);
        inner.InnerMethod();
    }


    public static void main(String[] args) {
        Outer outer = new Outer();
        System.out.println(outer.strOuter);
        outer.OuterMethod();
        //通过外部类调用runInner方法
        outer.runInner();
        //多重调用,创建内部类对象
        Inner inner = outer.new Inner();
        System.out.println(inner.strInner);
        inner.InnerMethod();
    }
}

2.成员内部类

成员内部类是定义在外部类中的类,它与外部类的其他成员变量和方法具有相同的访问权限(public、protected、default和private)。

成员内部类可以访问外部类的私有成员变量和方法,包括静态和非静态的。同时,外部类也可以通过实例化内部类对象来访问内部类的成员变量和方法。

代码中的体现

public class Outer {
    private String strOuter= "这是外部类中的私有成员变量";
    public void OuterMethod(){
        System.out.println("这是外部类中的公有成员函数");
        Inner inner = new Inner();
        inner.show();
        inner.InnerMethod();
    }

    //定义内部类
    public class Inner{
        public void show(){
            System.out.println(strOuter);

        }
        private String strInner = "这是内部类中的私有成员变量";
        public void InnerMethod(){
            System.out.println("这是内部类中的私有成员方法");
        }
    }

}

这段代码定义了一个成员内部类Inner,并在外部类Outer的方法OuterMethod()中实例化了内部类对象,并调用了内部类的方法。

OuterMethod()方法中,我们创建了一个内部类对象inner,然后通过inner.show()方法打印了外部类的私有成员变量strOuter的值。内部类可以直接访问外部类的私有成员变量。

接着,我们调用了内部类的InnerMethod()方法,打印了一条信息。

这段代码展示了成员内部类可以访问外部类的私有成员变量和方法,并且通过外部类对象来实例化和调用内部类对象。

public class Ts {
    public static void main(String[] args) {
        //间接访问
        Outer outer = new Outer();
        outer.OuterMethod();
        //直接访问
        Outer.Inner inner = outer.new Inner();
        inner.show();
        inner.InnerMethod();
    }
}

这段代码演示了如何通过间接访问和直接访问来访问内部类。

main方法中,我们首先创建了外部类对象outer,然后通过该对象调用了外部类的成员函数OuterMethod()。这是一种间接访问内部类的方式,因为我们在外部类的方法中实例化了内部类对象,并调用了内部类的方法。

接下来,我们使用直接访问方式来访问内部类。首先,我们通过outer.new Inner()创建了内部类对象inner,然后通过该对象调用了内部类的方法show()InnerMethod()。这是一种直接访问内部类的方式,因为我们直接通过外部类对象来实例化和调用内部类对象。

无论是间接访问还是直接访问,我们都能够访问内部类的成员变量和方法。

3.局部内部类

局部内部类是定义在方法内部的内部类。与成员内部类不同,局部内部类只在所属方法中可见,对于其他方法和类来说是不可见的。

局部内部类的特点:

  1. 只能在所属方法中被使用,无法在外部方法或其他类中使用。
  2. 局部内部类可以访问外部方法的局部变量和参数(final 和 effectively final 变量)。
  3. 局部内部类不能定义静态成员(static 成员)。
  4. 局部内部类可以访问外部类的所有成员,包括私有成员。

代码中的体现

public class Outer {
    private String strOuter = "外部类成员变量";
    public void outerMethod(){

        //局部内部类不加修饰符
        class Inner{
            public void show(){
                System.out.println(strOuter);
            }
            public void InnerMethod(){
                System.out.println("内部类的成员方法");
            }
        }
        Inner inner = new Inner();
        inner.show();
        inner.InnerMethod();
    }
}

这段代码定义了一个外部类 Outer,其中包含一个方法 outerMethod。在 outerMethod 方法中,定义了一个局部内部类 Inner

Inner 类是在 outerMethod 方法内部定义的,所以它只能在 outerMethod 方法内部使用。它具有两个成员方法:showInnerMethod

outerMethod 方法中,我们创建了 Inner 类的实例 inner,并调用了它的 showInnerMethod 方法。在 show 方法中,我们访问了外部类的成员变量 strOuter

public class Ts {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.outerMethod();
    }
}

直接通过外部类对象来调用

4.匿名内部类

匿名内部类是一种没有名字的类,在定义的同时实例化并使用。它通常用于简化代码,特别是在需要实现某个接口或继承某个类的情况下。

匿名内部类的语法和普通类定义相似,但是没有类名。它可以直接在方法中定义,也可以作为方法参数或返回值使用。它的定义通常包含在一个方法中,并且在方法中创建并使用

1.代码中的体现

public abstract class Inner {
    public abstract void show();
}

这段代码定义了一个抽象类Inner,具有一个抽象方法show。抽象类是不能直接实例化的,需要通过继承它的子类来创建实例。

在这个代码中,Inner类是一个抽象类,它包含了一个抽象方法show。抽象方法是没有具体实现的方法,子类必须实现这个方法。这是一种约束,确保子类都有相同的方法。

代码中的show方法定义了一个抽象方法,没有具体的实现。子类必须重写这个方法来提供具体的实现。

使用这个抽象类,需要创建一个继承它的子类,并实现show方法。例如:

public class InnerExts extends Inner{
    @Override
    public void show() {
        System.out.println("这是Inner子类中的show方法");
    }
}

这段代码定义了一个名为InnerExts的类,它继承了抽象类InnerInnerExts类必须实现继承自Inner抽象类的抽象方法show

InnerExts类中,重写了show方法,提供了具体的实现。在这个例子中,show方法会打印出"这是Inner子类中的show方法"。

public class Outer {
    public void OuterMethod(){
        new Inner() {
            @Override
            public void show() {
                System.out.println("这是匿名内部类");
            }
        }.show();
    }
}

这段代码定义了一个名为Outer的类,其中包含了一个方法OuterMethod

OuterMethod方法中,创建了一个匿名内部类。匿名内部类是一种没有显式声明类的特殊类型的类。它直接在代码中定义,并且通常用于只需要临时使用一次的情况下。

在这个例子中,匿名内部类实现了抽象类Innershow方法,并提供了具体的实现。在匿名内部类的show方法中,打印出"这是匿名内部类"。

通过创建匿名内部类的实例并调用其中的方法,可以执行匿名内部类的具体实现。

public class Ts {
    public static void main(String[] args) {
        new Outer().OuterMethod();
        new InnerExts().show();
        new Inner() {
            @Override
            public void show() {
                System.out.println("主方法中直接使用匿名内部类");
            }
        }.show();

    }
}

这段代码定义了一个名为Ts的类,其中包含了一个main方法。

main方法中,分别创建了三个对象并调用了它们的show方法。

  1. new Outer().OuterMethod():创建一个Outer对象,并调用其中的OuterMethod方法。在OuterMethod方法中,创建了一个匿名内部类并调用了它的show方法,输出结果为"这是匿名内部类"。

  2. new InnerExts().show():创建一个InnerExts对象,并调用其中的show方法。InnerExtsInner 的子类,它重写了show方法,并输出结果为"这是Inner子类中的show方法"。

  3. new Inner() { ... }.show():创建一个匿名内部类,并调用其中的show方法。在匿名内部类中重新实现了show方法,并输出结果为"主方法中直接使用"。

因此,最终输出的结果是:

这是匿名内部类
这是Inner子类中的show方法
主方法中直接使用

这段代码展示了在不同的场景中使用匿名内部类的方法。可以在方法内部直接创建匿名内部类并调用其中的方法。

2.匿名内部类的使用案例

public interface Run {
    void run();
}

这段代码定义了一个名为Run的接口,其中包含了一个抽象方法run

接口是一种抽象的数据类型,它定义了一组方法的签名,但没有具体的实现。接口可以被其他类实现,实现类需要提供具体的方法实现。

在这个接口中,只定义了一个run方法,该方法没有任何参数和返回值。实现该接口的类需要提供自己的run方法的具体实现。

这个接口可以用来表示某个对象可以执行运行的操作。实现该接口的类需要重写run方法,并在方法体中定义运行的具体逻辑。

public class Dog implements Run{
    @Override
    public void run() {
        System.out.println("狗叼着骨头跑");
    }
}

这段代码定义了一个名为Dog的类,该类实现了Run接口。

通过implements关键字,Dog类表示它将实现Run接口中定义的方法。

Dog类中,重写了run方法,即提供了run方法的具体实现。在方法体中,输出了"狗叼着骨头跑"。

通过实现Run接口,Dog类可以被视为一个可以执行运行操作的对象。其他代码可以通过调用run方法来让Dog对象执行运行操作。

public class whoRun {
    public void show(Run r){
        r.run();
    }
}

这段代码定义了一个名为whoRun的类,其中包含一个名为show的方法。

show方法的参数是一个Run接口类型的对象r,表示可以接受任何实现了Run接口的对象。

show方法内部,通过调用r.run()来执行传入对象的run方法。

通过这个show方法,可以将任何实现了Run接口的对象作为参数传入,并调用其run方法进行运行操作。这种设计方式实现了多态,提高了代码的灵活性和可扩展性。

public class Ts {
    public static void main(String[] args) {
        whoRun whoRun = new whoRun();
        Dog dog = new Dog();
        //使用多态的方式
        whoRun.show(dog);
        //使用匿名内部类
        whoRun.show(new Run() {
            @Override
            public void run() {
                System.out.println("猫叼着鱼跑");
            }
        });
        //使用Lambda函数
        whoRun.show(() -> System.out.println("猫叼着鱼跑"));
    }
}

这段代码定义了一个名为Ts的类,其中包含一个main方法。

main方法中,首先创建了一个whoRun对象和一个Dog对象。

接着,通过多态的方式,调用whoRun对象的show方法,将Dog对象作为参数传入。由于Dog类实现了Run接口,并重写了run方法,所以在show方法内部会调用Dog对象的run方法,输出"狗叼着骨头跑"。

接下来,使用匿名内部类的方式,创建了一个实现Run接口的匿名类对象,并重写了run方法,在run方法中输出"猫叼着鱼跑"。再次调用whoRun对象的show方法,将匿名类对象作为参数传入,会执行匿名类对象的run方法,输出"猫叼着鱼跑"。

最后,使用Lambda表达式的方式,创建了一个函数式接口Run的实现对象,实现了run方法,并在run方法中输出"猫叼着鱼跑"。再次调用whoRun对象的show方法,将Lambda表达式作为参数传入,会执行Lambda表达式的run方法,输出"猫叼着鱼跑"。

通过这段代码,演示了不同方式创建和使用实现了同一个接口的对象,并调用其方法实现不同的功能。这种灵活使用接口和多态的方式,增加了代码的可扩展性和复用性。

  • 27
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惊爆点大男主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值