首页 > 其他分享 >面向对象-高级篇

面向对象-高级篇

时间:2022-10-05 18:14:46浏览次数:43  
标签:void System 高级 面向对象 static println public out

类变量:

  • 什么是类变量? 一个可以被一个类所有对象共享的变量
  • 类变量关键字? static
  • 类变量语法? 访问修饰符 static 数据类型 变量名; [推荐使用]
  •                        static 访问修饰符 数据类型 变量名;
  • 入门案例:
    • count被child1和child2共享,只要是Child类的对象都可以共享该变量  
  • public class Test {
        public static void main(String[] args) {
            Child child1 = new Child("jack");
            child1.join();
            Child.count++;
            Child child2 = new Child("king");
            child2.join();
            Child.count++;
        }
    }
    class Child{
        String name;
        public static int count = 0;
        public Child(String name) {
            this.name = name;
        }
         public void join(){
             System.out.println(name);
         }
    }
  • 类变量的内存发布:

  • 类变量细节:

    • 类变量也叫静态变量
    • 类变量可以通过 - 类名.类变量名 或 对象名.类变量,来访问
    • 类变量是在类加载时初始化,就算没有创建对象,只要类加载,就可以访问类变量 - 重要
    • 类变量的生命周期是随着类加载开始,类消亡而销毁
    • public class Test {
          public static void main(String[] args) {
      //类变量,可以通过类名.类变量名称,或对象名.类变量来访问
      System.out.println(Child.count);
          }
      }
      class Child{
          static int count = 0;
      }

 类方法:

  • 什么是类方法?和类变量一样通过关键字static来实现共享
  • 类方法的语法?访问修饰符 static 数据返回类型 方法名(); - 推荐使用
  •                  static 访问修饰符 数据返回类型 方法名();
  • 类方法的使用场景?一般做为工具类来使用或者通用的方法(如:打印数组Arrays),来提高开发效率,通过类名去调用
  • 案例:
  • public class Test {
        public static void main(String[] args) {
            Child jack = new Child("jack");
            Child.payFee(1000);
            Child kind = new Child("kind");
            Child.payFee(2000);
            Child.showFee();//3000
        }
    }
    class Child{
        private String name;
        //累加学费
        public static double fee = 0;
    
        public Child(String name) {
            this.name = name;
        }
        //静态方法
        public static void payFee(double fee){
            Child.fee += fee;
        }
        //静态方法
        public static void showFee(){
            System.out.println(fee);
        }
    }
  • 类方法细节:

    • 类方法和普通方法都是随着类的加载而加载,将结构存储在方法区
    • 类方法中不能使用this和super
    • 类方法中只能访问类变量或类方法  
    • 普通成员方法,即可以访问非静态成员,也可以访问静态成员
    • class Child{
          String name;
          //类方法中不能使用this和super
          public static void payFee(double fee){
              System.out.println(this.name); //错误
              System.out.println(super.clone());//错误
              //类方法中只能访问类变量或类方法
              showFee();//错误
              System.out.println(name);//错误
          }
          public void showFee(){
              //普通成员方法,即可以访问非静态成员,也可以访问静态成员
              System.out.println(name);//正确
              payFee(11.1);//正确
          }
      }

main方法的理解:

  • main方法本虚拟机调用
  • java虚拟机需要调用类的main方法,使用main方法访问权限为public
  • java虚拟机在执行main方法时不必创建对象,所以是static
  • main方法的字符串类型数组参数,是在执行程序时传递
  • 细节:

    • main方法中,可以直接调用main方法所在类的的静态方法和静态属性
    • 不能直接调用非静态成员,必须创建一个实例底对象后才能调用
    • public class Test {
          private String name = "king";
          private static int age = 18;
          public static void show(){
              System.out.println("我可以被main调用");
          }
          public void show2(){
              System.out.println("我不是静态方法");
          }
      
          public static void main(String[] args) {
              show();//直接调用
              System.out.println(age); //直接调用
              Test test = new Test();
              test.show2(); //创建对象调用
              System.out.println(test.name);//创建对象调用
      
          }
      }
    • 如果在idea给main方法传参数

 

代码块: 

  • 什么是代码块?可以把它看成一个方法,可以在代码块中写逻辑语句,但它没有返回体,没有方法名,就在一个花括号中
  • 基本语法?[ 修饰符 ]{ 代码 }; - 分号可写可不写 
    • 修饰符:只能是static或者不写(有static的叫静态代码块,没有的叫普通代码块)
  • 案例:
  • class A{
        //静态代码块,随着类的加载而加载,只执行一次
        static{
            System.out.println("我是代码块A"); //2
        };
        //普通代码块,随着对象实例的创建而加载,创建一个对象,执行一次
        {
            System.out.println("我是代码块B"); //3
        };
    }
  • 细节(多看记住):

    • 静态代码块随着类的加载而执行,只会执行一次
    • 普通代码块在创建对象时而执行,创建一个对象执行一次
    • 类的加载情况:
      1. 创建对象实例(new)
      2. 创建子类对象实例,父类也会被加载(没父哪来的子)
      3. 使用类的静态成员
    • public class Test {
          public static void main(String[] args) {
      //        System.out.println(A.name); //输出结果:1.把键盘敲烂 2.king
      //        A a = new A();//输出结果 1.把键盘敲烂 2.king 3.普普通通
              B b = new B();//输出结果:1.把键盘敲烂 2.B代码块 3.普普通通
          }
      }
      class A{
          public static String name = "king";
          //静态代码块随着类的加载而执行,只会执行一次
          static{
              System.out.println("把键盘敲烂");
          };
      
          {
              System.out.println("普普通通");
          };
      }
      //创建子类对象实例,父类也会被加载
      class B extends A{
          static{
              System.out.println("B代码块");
          }
      }
    • 创建对象时,类中的调用顺序:
      1. 先调用静态代码块和静态属性的初始化
        1. 如果有多个静态代码块和静态属性变量初始化,则按照定义顺序执行,因为它们优先级一样
      2. 在调用普通代码块和普通属性的初始化
        1. 如果有多个普通代码块和普通属性初始化,则按照定义顺序执行,因为它们优先级一样、
      3. 最后调用构造器方法
    • public class Test {
          public static void main(String[] args) {
              A a = new A();
          }
      }
      class A{
          public static String name = "show()"; //1
          public static int a = show(); //1
          public int b = show2(); //3
      
          public A(int b) {
              System.out.println("可怜的构造器被最后调用"); //5
          }
      
          static{
              System.out.println("把键盘敲烂"); //2
          };
      
          {
              System.out.println("普普通通"); //4
          };
      
          public static int show(){
              System.out.println("我是show");
              return 0;
          }
          public int show2(){
              System.out.println("我是show2");
              return 0;
          }
      }
    • 构造器中 在默认隐藏了super( )和调用普通代码块 - 这是父子类都没有静态代码块或静态属性的执行流程
      • 理解:有继承关系,就先执行完父类的才执行到自己的  
    • public class Test {
          public static void main(String[] args) {
              B b = new B();
          }
      }
      class A{
          {
              System.out.println("A代码块");//1
          }
          public A() {
              //super()
              //调用本类代码块
              System.out.println("A无参构造");//2
          }
      }
      class B extends A{   
          {
              System.out.println("B代码块");//3
          }
          public B() {
              //super()
              //调用本类代码块
              System.out.println("B无参构造");//4
          }
      }
    • 继承关系:父类和子类都有静态代码和静态属性,普通代码块和普通属性和构造器,类的执行流程是?:

      1. 执行父类的静态代码块和静态属性(优先级一样,按顺序执行)

      2. 执行子类的静态代码和静态属性(优先级一样,按顺序执行)

      3. 执行父类的普通代码块和普通属性(优先级一样,按顺序执行)

      4. 执行父类的构造器方法
      5. 执行子类的普通代码块和普通属性(优先级一样,按顺序执行)

      6. 执行子类的构造器方法

    • public class Test {
          public static void main(String[] args) {
              new B02();//对象
          }
      }
      class A02 { //父类
          private static int n1 = getVal01();
          static {
              System.out.println("A02的一个静态代码块..");//(2)
          }
          {
              System.out.println("A02的第一个普通代码块..");//(5) 
          }
          public int n3 = getVal02();//普通属性的初始化
          public static int getVal01() {
              System.out.println("getVal01");//(1) 
              return 10;
          }
          public int getVal02() {
              System.out.println("getVal02");//(6) 
              return 10;
          }
          public A02() {//构造器
              //隐藏
              //super()
              //普通代码和普通属性的初始化......
              System.out.println("A02的构造器");//(7) 
          }
      }
      class B02 extends A02 { 
          private static int n3 = getVal03();
          static {
              System.out.println("B02的一个静态代码块..");//(4) 
          }
          public int n5 = getVal04();
          {
              System.out.println("B02的第一个普通代码块..");//(9)
          }
          public static int getVal03() {
              System.out.println("getVal03");//(3) 
              return 10;
          }
          public int getVal04() {
              System.out.println("getVal04");//(8) 
              return 10;
          }
          public B02() {//构造器
              //隐藏了
              //super()
              //普通代码块和普通属性的初始化...
              System.out.println("B02的构造器");//(10)
              // TODO Auto-generated constructor stub
          }
      }

单例设计模式:

  • 什么是单例设计模式?    单个实例的意思,就是采取某些办法让类的实例对象只有一个(饿汉式-懒汉式,就是经典的单例模式)
    • 什么是设计模式? 在大量的实践中总结出的代码结构,编程风格,已经解决问题的思考方式
  • 饿汉式:

    • 什么是饿汉式? 类加载的时,就已经创建对象实例 - 十分着急
    • 饿汉式实现步骤:
      • 所有化构造器
      • 类的内部创建对象
      • 向外部暴露一个静态的公共方法
    • public class Test {
          public static void main(String[] args) {
              King show = King.show();
              System.out.println(show);//com.Variable.King@1540e19d
              //类加载只加载一次
              King show2 = King.show();
              System.out.println(show);//com.Variable.King@1540e19d
          }
      }
      class King{
          private String name;
          private static King king = new King("jack");
      
          private King(String name) {
              System.out.println("构造器被调用");
              this.name = name;
          }
      
          public static King show(){
              return king;
          }
      }
  • 懒汉式:
    • 什么是懒汉式? 需要到创建对象实例,才会创建 - 不着急
    • 懒汉是实现步骤,和饿汉是一样,都是细节不一样
    • public class Test {
          public static void main(String[] args) {
              Idler show = Idler.show();
              System.out.println(show);//com.Variable.Idler@1540e19d
              //类加载只加载一次
              Idler show2 = Idler.show();
              System.out.println(show);//com.Variable.Idler@1540e19d
          }
      }
      class Idler{
          private String name;
          private static Idler idler;
      
          private Idler(String name) {
              this.name = name;
          }
      
          public static Idler show(){
              if (idler == null){
                  idler = new Idler("jack");
              }
              return idler;
          }
      }
  • 饿汉式和懒汉式对比:

    • 两种模式,都是为了对象的一个实例,只是创建时机不同
    • 饿汉式不存在线程安全问题,懒汉式存在线程安全问题
    • 饿汉式存在资源浪费问题,如果没有使用到它但它创建对象实例了,就浪费了,懒汉式是使用时才创建,不存在该问题  

final关键字:

    • 什么是final关键字? 表示最终的意思,可以用来修饰类、属性、方法和局部变量
    • 使用场景? - 总结:不希望本类被子类继承
      • 不希望本类被子类继承
      • 当类的属性不希望被修改时
      • 当局部变量不希望本修改时
      • 当类的方法不需希望本子类覆盖/重写时
    • final class AA{
      }
      //当类不希望被继承时,可以使用final修饰
      class BB extends AA{}
      
      class CC{
      
          private final String Name = "jack";
          public final void show(){
              //当类的某个属性不希望被修改时,可以用final修饰
              Name = "king";
      
          }
          public void show2(){
              //当局部变量不希望被修改时,可以使用final修饰符
              final int i = 10;
          }
      }
      
      class DD extends CC{
          //当父类的方法不想被子类覆盖/重写
          @Override
          public void show() {
              super.show();
          }
      }
  • 细节:

    • final修饰的属性又叫常量,一般用什XX_XX_XX来命名
    • final修饰属性时,必须赋值,标签以后不能修改,赋值可以在下面的其中一个:
      • 直接属性赋值 如:public final int i = 10;
      • 构造器赋值
      • 代码块赋值 
    • final修饰属性时,如果是静态属性,赋值可以在下面其中一个:
      • 直接赋值
      • 静态代码块
    • final不能被继承,但可以本实例化
    • 类不是final类,但是含有final方法,则该方法虽然不能被覆盖/重写,但可以继承
    • final不能修饰构造器
    • final和static搭配使用,效率更高,因为不会导致类的加载(底层编译器做了优化)
    • 是final类了,就没有必要将类中方法修饰为final方法(因为类不会本继承,方法也不会被覆盖/重写)
    • 包装类(Integer,Double,Float,Boolean等但是final),String也是final类 
    • public class Test {
          public static void main(String[] args) {
              //final类不能继承但能实例化对象
              CC cc = new CC();
              //不是final类,但是是方法是final方法,不可以本覆盖/重写,但可以本继承
              EE ee = new EE();
              ee.show(); //被继承的表示
              //用了final和static,不会导致类加载
              System.out.println(GG.i);
          }
      }
      class GG{
          public static final int i = 10;
          static {
              System.out.println("用了final和static,不会导致类加载");
          }
      }
      
      class FF{
          //final不能修改构造器方法
          public final FF() {
          }
      }
      
      final class CC{}
      
      class DD{
          public final void show(){
              System.out.println("敲坏键盘");
          }
      }
      
      class EE extends DD{
      
      }
      //普通属性赋值时
      class AA{
          //1.直接都有时赋值
          public final double TAX_RATE;
          //2.构造器赋值
          public AA(){
              TAX_RATE = 99.99;
          }
          //3.代码块赋值
          {
              TAX_RATE = 66.66;
          }
      }
      
      //静态属性赋值时
      class BB{
          //1.直接都有时赋值
          public static final double TAX_RATE = 88.88;
          //2.静态代码块赋值
          static{
              TAX_RATE = 99.99;
          }
      }

 抽象类:

  • 什么是抽象类?当父类的某些方法,需要声明,但不确定方法用来做什么的时候,就可以用抽象,那么方法就叫抽象方法,类就是抽象类、
    • 例:就是我的父类有一个方法,不知道具体用来做什么,但是要声明这个方法,然后用子类去基础并实现该方法  
  • 语法?方法:访问修饰符 abstract 返回类型 方法保名(); - - 没有方法体   类:abstract 类名{}; 
  • 抽象类的用途?抽象类的作用更多在于设计,设计者设计号后,让子类继承并实现。在框架和设计模式使用比较多
  • abstract class Employee{ //抽象类
        //抽象方法    
        public abstract void work();
    }
    class Manager extends Employee{
        //实现抽象方法
        @Override
        public void work() {
            System.out.println("经理/普通员工"+super.name+"工作中");
        }
    }
  • 细节:

    • 抽象类不能本实例化(类加载可以)
    • 抽象类库可以不包含abstract方法,就是抽象类可以没有抽象方法
    • 类中又了抽象方法,该类就必须声明为抽象类
    • abstract只能修饰类和方法,不能修饰属性和其它
    • 抽象类可以又任意成员(抽象类还是类)               
    • 抽象方法不能有主体
    • 一个类继承了抽象类就必须实现抽象方法,否则就把自己也声明为抽象方法就不用实现了
    • 抽象类不能使用,static、find、private来修饰,这些关键字和重写想违背
  • 重新类最佳实际 - 模板设计
    • 什么是模板设计?把公共的区域提取出来封装到一起
    • public class Test {
          public static void main(String[] args) {
              BB bb = new BB(); //继承理所应当的calculateTime方法也继承
              bb.calculateTime(); 
      
              CC cc = new CC();
              cc.calculateTime();
          }
      }
      abstract class AA{
          public abstract void obj();
          public void calculateTime(){
              long start = System.currentTimeMillis();
              obj(); //但调用到该方法时,动态绑定机制就上场了,会去看子类有没有,有就调用
              long end = System.currentTimeMillis();
              System.out.println("总共耗时:"+(end-start));
          }
      
      }
      class BB extends AA{
          public void obj(){
              long k = 0;
              for (int i = 1; i <= 900000; i++) {
                  k+=i;
              }
          }
      }
      class CC extends AA{
          public void obj(){
              long k = 0;
              for (int i = 1; i <= 900000; i++) {
                  k+=i;
              }
          }
      } 

接口:

  • 什么是接口?1.接口是java单继承的一种补充,2.接口规则了实现方法,实现接口的类必须实现方法
    • 例:1.小猴子只会爬树-这是继承老猴子的,小猴子学游泳是学鱼的-这就是实现接口,单继承补充
  • 语法:interface 接口名{....} -- 定义接口 ,class 类名 implements 接口名{....} -- 实现接口
  • 用途:定义规范例:我写一个接口规则数据库只能用统一的接口名实现,那么不管连接什么数据库的方法名都得到了统一等等
  • 案例演示:

    • public interface Usb {
          int i = 10; //接口可以有属性
          void show(); //抽象方法
      }
      class King implements Usb{
          int a = 20; //定义自己的属性
          @Override
          public void show() { //实现接口中的抽象方法
              System.out.println(Usb.i); //获取属性
          }
          public void show2(){
              System.out.println("定义自己的方法");
          }
      }
  • jdk7.0和jdk8.0接口的改变:

    • jdk7.0以前接口在是不能有默认方法和静态方法
    • jdk8.0以后接口在是可以有默认方法和静态方法
      • 默认方法需要加上default关键字
    • public interface Usb {
          void show();
          default public void show3(){
              System.out.println("jdk8以后可以写普通属性");
          }
          public static void show4(){
              System.out.println("jdk8以后可以写静态方法");
          }
      }
  • 细节:

    • 接口不能实例化
    • 接口的写的抽象方法是不用写abstract关键字的
    • 接口中所有的方法是public方法,接口在抽象方法,可以不用abstract修饰
    • 普通类实现接口,必须将该接口的所有方法都实现
    • 抽象类实现接口,不用实现接口方法 - 因为接口的里的方法就是抽象方法
    • 一个类可以同时实现多个接口
    • 接口中的属性只能是final的
    • //接口的修饰符只能是public和默认的,和了类的修饰符一样
      public interface Usb {
          //接口中的属性只能是find
          int i = 10; //等价于 int final static i = 10;
          //不用abstract来修饰方法为抽象方法
          void connect();
          //接口中的方法都是public方法
          //private void interrupt();
          default void interrupt(){
              //接口的访问通过接口名.属性名
              System.out.println(Usb.i);
          }
      }
      //接口不能继承其它类,但是可以继承多个别的接口
      interface Usb3 extends Usb{}
      //一个类同时实现多个接口
      class A_ implements Usb,Usb3{
          int a = 10;
          //一个普通类实现接口必须把接口方法都实现了
          //当然抽象类不用
          @Override
          public void connect() {
              System.out.println("连接Usb——A");
          }
          @Override
          public void interrupt() {
              System.out.println("连接Usb——A");
          }
      }
  • 实现接口VS继承类:

    • 问题?接口是让实现它的类去实现它的抽象方法,继承是让它的子类去继承它的属性方法(遵守访问修饰符),感觉上是差不多,那实际是什么样
    • 继承的价值:解决代码的复用性和可维护性
    • 接口的价值:设计 - 设计好合作规范(方法)让其它类去实现这些方法,比较灵活
    • 继承需要满足is-a的关系 - 就是小狗的继承类必须是动物,是有保存联系的
    • 接口只需要满足like-a的关系 - 就是小狗类但是我也可以去实现某个接口,如该接口中有游泳的方法,小狗就实现了游泳
  • 接口的多态:

    • 接口的多态和类的多态是一样的父类可以接收所有子类,接口就是可以接收实现它的类
    • public interface Usb {
          void show1();
          void show2();
      }
      class AA implements Usb{
          @Override
          public void show1() {
              System.out.println("连接Usb——A");
          }
      
          @Override
          public void show2() {
              System.out.println("断开Usb——A");
          }
          public void aao(){
              System.out.println("我是AA的特有方法");
          }
      }
      class BB implements Usb{
          @Override
          public void show1() {
              System.out.println("连接Usb——B");
          }
      
          @Override
          public void show2() {
              System.out.println("断开Usb——B");
          }
          public void bbo(){
              System.out.println("我是BB的特有方法");
          }
      }
      
      class king{
          Usb[] usb = new Usb[2];
          public void jk(){
              usb[0] = new AA();
              usb[1] = new BB();
              for (int i = 0; i < usb.length; i++) {
                  usb[i].show1();
                  usb[i].show2();
                  if (usb[i] instanceof AA){
                      ((AA)usb[i]).aao();
                  }
                  if (usb[i] instanceof BB){
                      ((BB)usb[i]).bbo();
                  }
              }
          }
      }

内部类:

  • 什么是内部类?就是在一个类的内部完整的嵌套一个类,被嵌套的就是内部类,嵌套类的叫外部类,至于其它的叫外部其它类
    • 内部类的本质还是一个  
  • 内部类分为4个?1.局部内部类 2.匿名内部类 3.成员内部类 4.静态内部类
  • 局部内部类:

    • 局部内部类是定义在外部类的局部位置,如方法中或构造器,并且有类名
    • 可以直接访问外部类的所有成员,包括私有的
    • 不能使用访问修饰符来修饰局部内部类,因为的地位是一个局部变量,但是可以使用final来修饰,局部变量可以使用final
    • 作用域:在定义它的方法和构造器中
    • 局部内部类---访问---外部类的成员(直接访问)
    • 外部类---访问---局部内部类成员(创建对象在访问,细节:在作用域里面访问)
    • 外部其它类---不能直接访问--局部内部类(局部内部类的地位是一个局部变量)
    • 外部类和局部内部类的成员重名,默认遵循就近原则,如果要访问外部类的成员(外部类名.this.成员)
      • 外部类.this.成员:外部类.this等于的是外部类的对象通过对象地址打印就可以清晰知道 
    • public class Test2 { //外部其它类
          public static void main(String[] args) {
              Mo mo = new Mo();
              mo.show();
              System.out.println("外部类的MO.this地址:"+mo);
          }
      }
      class Mo{ //外部类
          //可以自己访问外部类的所有成员,包括私有的
          private int i = 10;
          public void show(){
              //局部变量可以使用final
              final class M1{ //创建局部内部类 - 方法中
                  int i = 10;
                  void UU(){
                      //默认遵循就近原则,如果要访问外部类的成员(外部类名.this.成员)
                      System.out.println("我是内部类里的方法UU i="+i);
                      System.out.println("外部类i="+Mo.this.i);
                      //和外部类的mo是一样的
                      System.out.println("局部内部类的MO.this地址:"+Mo.this);
                  }
              }
              new M1().UU(); //调用内部类里的方法
          }
          //创建局部内部类 - 代码块中
          {
            class M2{
                void PP(){
                    System.out.println("我是内部类里的方法PP");
                }
            }
            new M2().PP(); //调用内部类里的方法
          };
      }
  • 匿名内部类:

    • 什么是匿名内部类?写在外部类的局部位置,没有类名,本质上就是继承或实现了父类或接口的一个类(通过底层分析知道)
    • 什么场景使用?做为参数传递时用的比较多
    • 匿名内部类是定义在外部类的局部位置,如方法中或构造器
    • 匿名内部类没有类名(本质上是有的,后面会说)
    • 语法:返回实例 = new 类/接口/抽象类(参数列表){类体};
    • 匿名内部类可以直接访问外部类的私有成员,包括私有的
    • 不能添加访问修饰符,它的地位是局部变量,final还是可以的
    • 作用域:定义它的代码在或方法中
    • 外部类不能访问匿名内部类,因为它的地位是局部变量
    • 外部类和匿名内部类的成员重名,默认遵循就近原则,如果要访问外部类的成员(外部类名.this.成员) 
    • public class Test {
          public static void main(String[] args) {
              M1 m1 = new M1();
              m1.show();
              m1.show2();
              m1.show3();
          }
      }
      class M1{
          /*
          1.jdk底层创建匿名内部类M1$1,立刻创建了M1$1实例,并且把地址返回给m2
          2.匿名内部类使用一次,就不能使用了:
              创建的M1$1语句返回对象给对象了就消失了,但对象可以多次使用
              底层方向 - 普通类的匿名内部类
          * class M1$1 extends M2{
          *       @Override
                  public void Ak() {
                      super.Ak();
                  }
          * }
          * */
          int L = 99;
          public void show(){
              M2 m2 = new M2(){
                  @Override
                  public void Ak(int i) {
                      super.Ak(i);
                      System.out.println(L);//直接访问外部类成员
                  }
              };
              m2.Ak(100);
              m2.Ak(100);
              //匿名内部类是没有类名的实际是有的,在底层中会分配外部类名加$1(M1$1就是它的类名)
              System.out.println("m2="+m2.getClass());//M1$1
          }
          /*
              底层分析 - 接口的匿名内部类
          * class M1$2 implements La{
          *       @Override
                  public void Lv() {
                      System.out.println("接口匿名内部类");
                  }
          * }
          * */
          public void show2(){
              La la = new La(){
                  @Override
                  public void Lv() {
                      System.out.println("接口匿名内部类");
                  }
              };
              la.Lv();
              System.out.println("la="+la.getClass());//M1$2
      
          }
          /*
              底层分析 - 抽象类的匿名内部类
          * class M1$3 extends Lv{
          *       @Override
                  void Ck() {
                      System.out.println("抽象类的匿名内部类");
                  }
          * }
          * */
          public void show3(){
               Lv lv = new Lv(){
                  @Override
                  void Ck() {
                      System.out.println("抽象类的匿名内部类");
                  }
              };
              lv.Ck();
              System.out.println("lv="+lv.getClass());
          }
      }
      class M2   {
          public M2() {
              System.out.println("我被调用了M2的构造器");
          }
      
          public void Ak(int i){
              System.out.println("我只想被调用一次"+i);
          }
      }
      interface La{
          void Lv();
      }
      abstract class Lv{
          abstract void Ck();
      }
  •  成员内部类:

    • 什么是成员内部类?定义在成员位置的类[没有static关键字](前面说到的局部内部类是定义在方法在或代码块中)
    • 成员内部类可以添加访问修饰符,因为它的地位在成员
    • 成员内部类可以直接访问外部类成员,包含私有的
    • 成员内部类遵循就近原则,如用重名就通过(外部类名.this.成员)
    • 外部类要访问成员内部类需要先创建对象在访问
    • 作用域:在外部类的整个类体
    • 外部其它类要访问成员内部类两种方法:
      • Tom.Outer01 outer01 = new Tom().new Outer01();
        • 理解:new Outer01()当成一个成员,只是它是类摆了  
      • Tom.Outer01 outer011 = new Tom().say2();
        • 理解:通过方法返回成员内部类的对象
    • public class Test {
          public static void main(String[] args) {
              //外部其它类访问成员内部类 方法1
              //理解:new Outer01()当成一个成员,只是它是类摆了
              Tom.Outer01 outer01 = new Tom().new Outer01();
              outer01.show();
              //外部其它类访问成员内部类 方法2
              //理解:通过方法返回成员内部类的对象
              Tom.Outer01 outer011 = new Tom().say2();
              outer01.show();
          }
      }
      class Tom{
          private int i = 10;
           public class Outer01{ //成员内部类(苦于添加任何访问修饰符)
              public void show(){
                  int i = 100;
                  System.out.println("我是成员内部类里的show方法");
                  System.out.println(i);//直接访问外部类成员(包含私有的)
                  System.out.println(Tom.this.i);//遵循就近原则,如果重名就通过(外部类名.this.成员)
              }
          }
          public void say(){
              Outer01 outer01 = new Outer01(); //外部类要访问成员内部类需要先创建对象在访问
              outer01.show();
          }
          public Outer01 say2(){
              Outer01 outer01 = new Outer01();
              return outer01;
          }
      }
  • 静态成员内部类:

    • 什么是静态成员内部类?写在外部类的成员位置[有static关键字]
    • 可以直接访问外部类成员方法,包含私有的(注意:静态只能访问静态)
    • 可以添加访问修饰符,因为地址是一个成员
    • 作用域:外部类的整个类体
    • 外部类访问静态成员内部类,需要先创建对象
    • 静态成员内部类遵循就近原则,如用重名就通过(外部类名.成员)-因为是静态就不需要this了
    • 外部其它类要访问成员内部类两种方法:
      • Tom.Outer01 outer01 = new Tom.Outer01();
        • 理解:相当于Tom去调用它的静态成员  
      • Tom.Outer01 outer011 = new Tom.say2();
        • 理解:去调用方法返回静态成员内部类的对象
    • public class Test {
          public static void main(String[] args) {
              //1.理解:相当于Tom去调用它的静态成员 
              Tom.Outer01 outer01 = new Tom.Outer01();
              //2.理解:去调用方法返回静态成员内部类的对象  
              Tom.Outer01 outer011 = Tom.say2();
          }
      }
      class Tom{
          private static String name = "Jack";
          //2.可以添加访问修饰符,因为地址是一个成员
          public static class Outer01{
              String name = "King";
              public void show(){
                  //1.以直接访问外部类成员方法,包含私有的(注意:静态只能访问静态)
                  System.out.println("name="+name);
                  //7.静态成员内部类遵循就近原则,如用重名就通过(外部类名.成员)-因为是静态就不需要this了
                  System.out.println("name="+Tom.name);
              }
          }
          //5.外部类访问静态成员内部类,需要先创建对象
          public void say(){
              Outer01 outer01 = new Outer01();
              outer01.show();
          }
          public static Outer01 say2(){
              Outer01 outer01 = new Outer01();
              return outer01;
          }
      }

       

                             

      

 

 

                    

    

                         

 

 

 

 

 

   

  

标签:void,System,高级,面向对象,static,println,public,out
From: https://www.cnblogs.com/Mr-shne/p/16698784.html

相关文章