面向对象高级

114 阅读5分钟

面向对象高级

四种内部类

1.局部内部类

// 局部内部类的使用:
        //1.局部内部类是定义在外部类的局部位置,比如方法,有类名
        //2.局部内部类可以直接访问外部类的所有成员,包括私有的
        //3.外部类访问内部类,  创建对象 在访问  (在作用域中创建)
        //4.不能添加访问修饰符,可以用final 修饰 防止其他类继承
        //5.作用域 (方法或代码块)

        //** 局部内部类定义在方法/代码块中
        //** 作用域在方法体或代码块中
        //**  本质还是类

        //6.外部其他类  不能访问 内部其他类 (例如main方法中)
        //7.如果外部其他类和内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用外部类名+this.成员

//实例讲解:

        out01 out01 = new out01();
        out01.f1();
        System.out.println(out01);  // out01的地址

    }
}
class out01{

    private int n = 1;
    public void f(){
        System.out.println("外部类的方法");
    }
   public void f1(){  // 方法中定义局部内部类
     class inner01{   //final 防止其他内部类的继承
        public void f2(){
            int n = 5;
            System.out.println("n = " + n);
            System.out.println("n = " + out01.this.n);
            System.out.println("n = " + out01.this);//out01的地址
            f();
        }
    }

        inner01 inner01 = new inner01();   // 需要创建对象才能使外部类调用内部类的方法
     inner01.f2();
        // class inner02 extends inner01 { }
    }
   {
     class inner03{   在代码块中定义内部类

       }
    



2.匿名内部类(重点)

//匿名内部类的引入: 例如
// 匿名内部类

        // 基于接口的匿名内部类
        //1.需求:想使用IA接口,并创建对象
        //2.传统方式:写一个类,实现该接口,并创建对象
        //3.需求: 只使用一次tiger 后面不使用
        //4.可以使用匿名内部类简化开发
        //5.tiger的编译类型 IA  运行类型 匿名内部类  (只想使用一次,但多个对象的时候,不需要创建多个类来实现接口)
        //6.匿名内部类用一次就不能使用了,但是创建的对象还是能使用


out04 out04 = new out04();
        out04.method();


       

    }


}
class out04{

  private int n = 100;
  public void method(){
       /*
      底层代码  class outer04$1 implements IA{
           @Override
          public void cry() {   //匿名内部类
              System.out.println("老虎叫唤");
          }
   
   
       */
      IA ia = new IA() {  // 重写方法
          @Override
          public void cry() {   //匿名内部类
              System.out.println("老虎叫唤");
          }
      };
      ia.cry();// 创建对象 让外部类调用内部类
      System.out.println(ia.getClass());
  }

interface IA{
    public void cry();
}
//class tiger implements IA{  // 传统方法
//
//    @Override
//    public void cry() {
//        System.out.println("老虎叫唤");
//    }
//}

    
    //基于类的匿名继承类  Father
       /*
      底层代码  class outer04$1 extents Father{
           @Override
          public void cry() {   //匿名内部类
              System.out.println("老虎叫唤");
          }
      }
       */



//使用细节:
//1.匿名内部类即使类的定义同时本身也是个对象,从语法上看,既有定义类的特征,也有创建对象的特征
//2.可以直接访问外部类的所有成员
//3.不能添加访问修饰符
//4.作用域  方法  代码块
//5.匿名内部类访问外部类的下成员  直接访问
//7.外部其他类(例如main中)  不能访问   匿名内部类 (—就是一个局部变量—)
//8.如果外部类和匿名内部类的成员重名时,匿名内部类访问时遵循就近原则  如果想要访问外部类的成员使用外部类名.this.成员
//9.使用场景: 当只需要调用一次时 不需要在写一个类 起方法   只需要写个匿名内部类 既节约了内存 有减轻了代码量
访问方式  两个方式
    public class AnonymousInnerClass02 {
    public static void  main(String [] args){

        out05 out05 = new out05();
        out05.f1();

    }
}
class out05{
    private int n1 = 99;
    public void f1(){
        // 第一种写法
        Person person = new Person(){  // 匿名内部类
//            public void hi(){
//                System.out.println("你好");    //如果没有重写调用哈哈  还是按继承关系运行
//            }

        };
        person.hi();  //运行类型是out05$01

     //   第二种写方法
        new Person(){

            public void ok(){


                System.out.println("好的");
            }
        }.ok();    // 不创建对象 最后.方法;


    }


}
class Person{

    public void hi(){
        System.out.println("哈哈");
    }

    public void ok(){
        System.out.println("okok");
    }

}
//小试牛刀
public class AnonymousInnerClass04 {
    public static void main(String [] args){

        Cellphone cellphone = new Cellphone();
        cellphone.alarmClock(new Bell() {   // 匿名内部类
            @Override
            public void ring() {

            }
        });
        x1(new Bell() {
            @Override
            public void ring() {
                System.out.println("懒猪起床了");
            }
        });
        x1(new Bell() {
            @Override
            public void ring() {
                System.out.println("小伙伴们上课了");
            }
        });


    }

    public static void x1(Bell bell){
        bell.ring();
    }

}
interface Bell{

    public void ring();

}
class Cellphone{

    public void alarmClock(Bell bell){  // 写入接口
        bell.ring();
    }
}

3.成员内部类

 // 成员内部类: 定义在外部类的成员位置,并且没有static的修饰
        //1.可以直接访问外部类的所有成员
        //2.可以添加访问修饰符  因为本身就是成员
        //3.作用域: 和其他的外部类的成员方法一样,在外部类的方法中创建对象 在调用对象
        //4.成员内部类  访问  外部类  直接访问
        //5.外部类访问内部类  创建对象在访问***
        //6.外部其他类访问成员内部类
        //7.重名用this  用法和之前一样
//实例讲解
out out = new out();
        out.t1();

        //5.外部类访问内部类  创建对象在访问 一   先写类名 在new 内部类
        MemberInnerClass.out.inner inner = out.new inner();
        inner.m();
        // 二  在外部类写一个方法 返回inner的对象

        MemberInnerClass.out.inner instance = out.getInstance();
        instance.m();

    }


}
class out{

    private int n1 = 100;

    class inner {
        int n1 = 520;
        public void m(){
            System.out.println("n1 =  " +  n1 +  "  外部类的" + out.this.n1);
        }


    }
    public void t1(){  // 创建公共的方法
        inner inner = new inner();
        inner.m();
    }
    public inner getInstance(){
        return new inner();

    }


}

4.静态内部类

 //静态内部类  定义在外部类的成员位置  用static修饰
        //1.可以直接访问外部类的静态成员 但是不能访问非静态成员
        //2.可以添加访问修饰符,本身就是成员
        //3.作用域 同类的其他成员,为整个类体
        //4.静态内部类访问外部类的静态成员 直接访问
        //5.外部类访问静态内部类  创建对象在访问
        //6.重名  和this的机制一样但是不使用this  外部类名.属性
//实例讲解
 out01.inner01 inner01 = new out01.inner01(); // 一 可通过类名直接访问
        inner01.m1();

        out01 out01 = new out01();
        out01.t2();

        // 编写一个方法 返回对象
        StaticClass.out01.inner01 inner011 = out01.get();
        inner011.m1();

    }
}
class out01{

public static int n1 = 1314;
    static class  inner01{

        int n1 = 666;
        public void m1(){
            System.out.println(n1 + "  " + out01.n1);
        }
    }
    public static void t2(){
        inner01 inner01 = new inner01();
        inner01.m1();
    }
    public static inner01 get(){
        return new inner01();
    }

}