Java入门需要了解(面向对象之内部类-十六)

本文介绍了Java内部类的样式,详细讲解了内部类的特点,包括可以直接访问所属类的所有成员,以及如何被成员修饰符修饰。还探讨了局部内部类的规则,特别是它们只能访问final修饰的局部变量。此外,匿名内部类的概念也被阐述,它是内部类的一种简写形式,必须继承或实现外部类或接口。最后,提到了匿名内部类在函数参数为接口类型和扩展方法时的应用场景。
摘要由CSDN通过智能技术生成

将一个类定义在另一个类里面,对里面那个类,就叫内部类(嵌套类,内置类)

内部类样式


class Out{
	//内部类
	class Inner{
	
	}
}
  • 生成的class文件样为 Out$Inner.class

内部类的特点

  • 内部类可以使用所属类的所有成员
class Out{
	private int x=5;
	class Inner{
		void print(){
			System.out.println("Inner print"+x);
		}
	}
	public void show(){
		Inner in = new Inner();
		in.print();
	}
}
  • 所属类要访问内部类的成员,则需要创建对象
  • 内部类定义在成员的位置,所以可以被成员修饰符修饰,private,protected,public
  • 直接访问内部类的定义格式
class Out{
    private int x=5;
    class Inner{
        void print(){
            System.out.println("Inner print"+x);
        }
    }
    public void show(){
        Inner in = new Inner();
        in.print();
    }
}

class TestInnerClass {
    public static void main(String[] args) {
        Out.Inner in = new Out().new Inner();
        in.print();
    }
}
  • 静态内部类的创建方式,可以直接使用,不常用static
class Out{
    private int x=5;
    static class Inner{
        void print(){
            System.out.println("Inner print");
        }
        
       static void test(){
            System.out.println("test");
        }
    }
    public void show(){
        Inner in = new Inner();
        in.print();
    }
}

class TestInnerClass {
    public static void main(String[] args) {
       	//内部类方法调用
        Out.Inner in = new Out.Inner();
        in.print();
        //内部类静态方法调用
        Out.Inner.test();
    }
}
  • 如果内部类有静态成员,则该内部类也必须是静态的
  • 内部类之所以能访问外部类的成员,是因为内部类持有了外部类的引用(外部类ming.this)

局部内部类

  • 内部类可以放在局部位置上
class Out{
    int num=10;
    void show(){
    	//类定义在方法内
        class Inner{
            void showInner(){
                System.out.println("showInner"+num);
            }
        }
        Inner inner = new Inner();
        inner.showInner();
    }
}
 class TestInnerClass2 {
     public static void main(String[] args) {
         new Out().show();
     }
}
  • 局部内部类中,只能访问局部中被final修饰的局部变量
class Out{
    int num=10;
    void show(){
        int x=2;
        //这里这样就会报错了,因为局部内部类只能访问被final修饰的变量,如果未加,则编译器自动加上final
        //所以x=3报错
        x=3;
        class Inner{
            void showInner(){
                System.out.println("showInner="+x);
            }
        }
        Inner inner = new Inner();
        inner.showInner();
    }
}
 class TestInnerClass2 {
     public static void main(String[] args) {
         new Out().show();
     }
}

匿名内部类

  • 匿名内部类,其实就是内部类的简写格式。
  • 匿名内部类的前提是:内部类必须继承或者实现一个外部类或者接口。
    抽象类
/**
 * 抽象父类
 */
abstract class Parent {
    abstract void show();
}

class Out {
    public void function() {
        //匿名内部类的定义
        new Parent() {
            @Override
            void show() {
                System.out.println("show");
            }
        }.show();
    }
}

class UnName {
    public static void main(String[] args) {
        new Out().function();
    }
}

接口

/**
 * 接口
 */
interface Parent {
    public void show();
}

class Out {
    public void function() {
        //匿名内部类的定义
        new Parent() {
            @Override
            public void show() {
                System.out.println("show");
            }
        }.show();
    }
}

class UnName {
    public static void main(String[] args) {
        new Out().function();
    }
}
  • 匿名内部类的格式 new 父类[接口]{匿名类实现内容+自己的内容}

匿名内部类的使用场景

  • 当函数的参数是接口类型时,而且接口中的方法不超过三个,可以使用匿名内部类作为实际参数进行传递,方法不超过三个,主要是方法过多会使得该类过于庞大,不便于阅读。
    扩展方法时,直接使用
class Out {
    public void function() {
        //匿名内部类的定义
        new Object() {
            public void show() {
                System.out.println("show1");
            }
        }.show();
    }
}

class UnName {
    public static void main(String[] args) {
        new Out().function();
    }
}

扩展方法时使用变量接收则编译错误

class Out {
    public void function() {
        //匿名内部类的定义
       Object obj =  new Object() {
            public void show() {
                System.out.println("show1");
            }
        };
       obj.show();
    }
}

class UnName {
    public static void main(String[] args) {
        new Out().function();
    }
}

原因在于子类对象被类型提升之后,就不能使用子类的特有方法了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值