【面向对象】内部类

什么是内部类?

顾名思义,在类A中定义了一个类B,那么类B就是内部类。


内部类的访问特点:

1.内部类可以直接访问外部类的成员,包括私有。
2.外部类要访问内部类的成员,必须创建对象。


 成员内部类

 

 成员内部类不用static修饰,如果使用,则为静态内部类

 成员内部类中的成员变量可以用static修饰(JDK16及以上


  如何创建成员内部类的对象

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

public class Outer { //外部类Outer
    String name;
    
    class Inner{ //内部类Inner

    }
}
public static void main(String[] args) {

    Outer.Inner n =new Outer().new Inner();
}

 new Outer ()可理解为外部类的对象,是一个调用者,调用内部类Inner的对象,然后将对象的地址值赋值给对象n


 private修饰内部类

 如果内部类使用private修饰,上述方法将会报错,因为被private修饰的方法只能在本类使用

private class Inner{ //private修饰内部类Inner
}

被private修饰的方法只能在本类使用,既然如此,我们可以在本类的外部类中定义一个方法 “getInstance” ,将其返回值定义成内部类对象,那么我们在其他类中调用此方法就可以间接定义内部类的对象。

public class Outer { //外部类Outer
    String name;
    
    private class Inner{ //private修饰内部类Inner
    }
    public Inner getInstance(){
        return new Inner();
    }
}
public static void main(String[] args) {
        
     Outer o =new Outer();
     o.getInstance();
}

 内部类方法如何调用外部类成员变量?

 内部类方法调用内部类成员变量的格式为 “ this.变量 ”,

 内部类方法调用外部类成员变量的格式为 “外部类名.this.变量

public class Outer { //外部类
    int a=10;

     class Inner{ //内部类
         int a=20;
        public void show() //本方法
        {
            int a=30;
            System.out.println(Outer.this.a);
            System.out.println(this.a);
            System.out.println(a);
        }
    }
}
public class Inner_test {
    public static void main(String[] args) {

        Outer.Inner oi = new Outer().new Inner();
        oi.show();
    }
}

 总结


静态内部类

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


如何调用静态类中的静态方法?

外部类名.内部类名.方法名();

Outer.Inner.show();

如何调用静态类中的非静态方法?

 先创建对象,对对象调用

Outer.Inner oi = new Outer.Inner();
   oi.show();

 运行

public class Outer { //外部类
    static class Inner{ //内部类
        public static void show() //定义静态方法
        {
            int a=30;
            System.out.println(a);
        }
        public void show2() //定义非静态方法
        {
            int a=30;
            System.out.println("20");
        }
    }
}
public class Inner_test {
    public static void main(String[] args) {

        Outer.Inner.show(); //调用静态方法

        Outer.Inner S1 = new Outer.Inner();
        S1.show2(); //调用非静态方法
    }
}


匿名内部类

 匿名内部类格式

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

 Swim是一个接口类,其中有方法swim

public interface Swim {
    public void swim();
}

 以下是一个以Swim接口为基础的匿名内部类

new Swim(){
    @Override
    public void swim() {
        System.out.println("重写后的游泳方法");
    }
};

 我们可以将括号里的这部分看做是一个没有名字的类

             {
    @Override
    public void swim() {
        System.out.println("重写后的游泳方法");
    }   
};

 而 new Swim+这个没有名字的类则可以理解为创建了一个此匿名类的对象

new Swim(){
    @Override
    public void swim() {
        System.out.println("重写后的游泳方法");
    }
};

既然创建了此类的对象就自然可以对其自己的方法进行调用,“ .swim

new Swim(){
    @Override
    public void swim() {
        System.out.println("重写后的游泳方法");
    }
}.swim();

 定义的匿名内部类new后如果是一个接口,就为实现关系,如果是一个,就为继承关系

new Swim(){ //Swim为接口,实现关系
    @Override
    public void swim() {
        }
};
        
new Animal(){ //Animal为类,继承关系
    @Override
    public void eat() {
        }
};

总结 

        如果我们需要用到一个方法,且这个方法只使用一次,由于这个方法存在抽象类父类中,如果想要调用此方法就需要重新创建一个子类来继承父类,对此方法进行重写,然后创建一个子类的对象对此方法进行调用。但我们只使用这个方法一次,却要创建一个类来实现,这样显然很笨比很不划算。

        于是我们可以使用匿名内部类,直接在new后写父类/接口的名字,匿名内部类是一个对象,而这个对象是以括号内的内容创建出来的。

        在大括号的无名类内对父类/接口的抽象方法进行重写,然后采用下图这种格式直接.swim调用,省去了重新定义一个类的麻烦,它的本质是一个 带具体实现的父类或者接口匿名的子类对象

new Swim(){
    @Override
    public void swim() {
        System.out.println("重写后的游泳方法");
    }
}.swim();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值