• 面向对象大总结


    面向对象

    关于面向对象的知识点理解

    面向对象:

    是设计者思维,是在创造某个产品时的,从宏观角度把握、整体上分析整个系统。
    解决复杂、需要协作的问题时使用面向对象。也就是怎么设计这个事物?比如:造车就是面向对象的思考。(整体设计)
    面向过程考虑谁来做?以类/方法为最小单位

    面向过程:

    是执行者思维,解决简单问题时使用面向过程。比如:如何开车?就是面向过程的思考。(执行和处理数据)
    面向过程考虑怎么做?以函数为最小单位
    二者相辅相成不是独立的。
    属性是独享的,方法是共享的。

    方法的重载

    关于类、方法、构造器

    属性
    类可以看作是一个模版,或图纸,系统根据类的定义来造出对象。
    类叫:class。对象:我们叫做Object(目标),instance(实例)。
    属性 是用来定义该类或该类对象的数据或者静态特征。
    方法 用于定义该类或该类的行为特征和功能实现。方法是类和对象行为特征的抽象。方法很类似于面向过程中的函数。
    方法其实就是在该类下面,所有属性共有的特征。

    构造器的4个要点:

    1.构造器通过 new 关键字调用!
    2.构造器虽然有返回值,但 不能  定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值
    3.如果我们没有定义构造器,则编译器会 自动定义 一个无参数的构造方法。如果已定义则编译器 不会 自动添加!
    4.构造器的方法名 必须 和类名一直(class 后面的类名)

    构造器的作用:不是创建对象,因为在创建之前这个对象已经创建好了。并且对象有默认的初始值
    调用构造器的目的只是给属性进行赋值的操作。

    ⚠️注意:我们一般不会在构造器中进行初始化操作,因为那样每个属性的值是一样的。
    在重载构造器之后,系统不会在给你分空构造器,这时候调用则会出错

    与顺序没有关系,可以随便写

    成员变量、局部变量和静态变量的区别

    在(成员变量)栈、在(局部变量)堆、在(静态变量)方法区里。
    (1)在类中的位置不同
    成员变量:类中方法外
    局部变量:方法定义中或者方法声明上(代码块中)
    (2)在内存中的位置不同
    成员变量:在堆中
    局部变量:在栈中
    (3)生命周期不同
    成员变量:随着对象的创建而存在,随着对象的消失而消失
    局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
    (4)初始化值不同
    成员变量:有默认值
    局部变量:没有默认值,必须定义,赋值,然后才能使用。需要初始化值

    this的用法

    this的本质就是创建好的对象的地址.由于在构造方法调用前,已经创建。因此,在构造方法中也可以使用this代表当前对象。
    构造器不是用来建对象的,只是用来初始化对象的属性

    加深理解this:





    创建对象的4步:

    1.分配对象的空间,并对对象成员初始化为0或空
    2.执行属性值的显式初始化(比如int id;哪默认为0,int id =3,则为3)
    3.执行构造方法
    4.返回对象的地址给相关的变量

    this 最常用的用法:

    1.this是用于指明当前对象,最常用的形式(在构造方法中,指向初始化的对象)如下

     public User(int id, String name) {
            System.out.println ("正在初始化已经创建好的对象" + this);//this指代的就是这个刚被创建出来的对象
            this.id = id;//不写this无法区分成员变量id(在堆中,在类中方法外,有默认值)和局部变量id(方法定义或方法声明中,在栈中,必须定义,赋值才可以使用)
            this.name = name;
        }
    
     public void login(){
                System.out.println (this.name+"需要登录!");//不写this效果一样
            }
    
            public User(int id,String name,String pwd){
            this(id,name);//this(),可以用于调用其他构造器,但必须位于第一行
            }
    

    2.this可以用于重载的构造方法中,但必须位于第一行
    3.this 不能用于static方法中(this是必须从属对象,main中没有对象,属于类)

    static用法

    public class Demo {
        int id;
        static int sid;
        public void a() {
            System.out.println ("---------a");
            System.out.println (sid);
            System.out.println (id);
        }
    
        //1.static和public 是修饰符,并列的没有先后顺序,先写谁都可以
        static public void b() {          //sid 是先于对象加载的
          //  a();//3.在静态方法中不能访问非静态方法
            System.out.println ("---------b");
            System.out.println (sid);
           // System.out.println (id);//2.在静态方法中不能访问非静态的属性
           // System.out.println (this.id);//4.在静态方法中不能使用this关键字
        }
    
        public static void main(String[] args) {
            Demo d = new Demo();
           // Demo.a();//5.非静态的方法可以用对象名.方法名去调用,不能用类.方法名
            d.a ();
    
            Demo.b ();//6'静态的方法可以用对象名.方法;类名.方法名(推荐)去调用
            d.b ();
            
            b();//在同一个类中可以直接调用
        }
    }
    

    static 声明的成员变量为静态成员变量/类变量,生命周期和类相同,声明的方法叫静态方法,static修饰的都是位于类里面不是对象里面

    虚拟机内存内存简单三个分区域:

    stack栈,heap堆、方法区 method area

    构造方法则在栈中进行,而方法代码则在方法区里

    虚拟机栈(stack)特点:

    1.栈描述的是方法执行的内存模型,每个方法被调用都会创建一个栈(存储局部变量、操作数、方法出口等)
    2.jvm为每个线程创建一个栈,用于存放线程执行的方法信息(实际参数、局部变量等)
    3.栈属于线程私有,不能实现线程共享
    4.栈存储,先进后出,后进先出
    5.栈是系统分配的速度快,是连续内存空间,构造方法需要开辟一个栈帧

    堆(heap)特点:

    1.堆用于存储创建好的对象和数组(数组也是对象)
    2.jvm只有一个堆,被所有线程共享
    3.堆是不连续的内存空间,分配灵活,速度慢

    方法区(静态区,也是堆)特点:

    1.只用于存储类和常量相关信息
    2.存放程序永远不变或者唯一的内容。(类信息【class对象、静态变量、字符串常量)

    内存分析

    总结:

    1.进行创建对象之时,会先在方法区加载Person 类字节码信息,以及在堆中创建默认对象,并默认做了初始化,有地址
    2.在之后会调用new关键字,调用构造器,构造器是一个方法会开辟一个栈帧,先把值赋给形参,再把值赋给局部变量,完成赋值。方法的栈消失(形惨、局部变量)在栈中消失。(字符串会在方法区的常量池里)
    3.对象已经创建好,将值赋给P。
    (1)简单的代码分析


    (2)
    (3)


    结果分析:

    包机制(package import)

    package

    包名:域名倒着写即可,再加上模块名,便于内部管理类。如:com.sur.test
    解决:类的同名和类的管理
    com.gao和com.gao.car,这两个包没有包含关系,但两个完全独立的

    jak中的主要包

    java.lang 包含Java语言的核心类。如:String、Math、System等等(可以直接用)
    java.awt
    java.net
    java.io
    java.util
    **

    导入类import

    若要是用其他包的类,需要使用import 导入,从而通过在本类中直接通过类名调用
    注意:java 默认导入java.lang包下的所有类,可直接使用;
    若导入的两个同名类,只能用包名+类名来显示调用相关类。如:

    java.util Date d  = new java.util.Date();
    

    静态导入:

    静态导入(static import)作用是用于导入指定类的静态属性和静态方法,这样我们可以直接使用静态属性和静态方法。

    import static java.lang.Math.*;//导入Math类的所有静态属性
    import static java.lang.Math.PI;//导入Math类的PI属性
    

    继承

    继承的作用:

    1.代码的复用,更易实现类的拓展;2.方便对事物的建模(对于相同的内容的复用)

    extends (拓展)

    继承可以使得子类具有父类的属性方法或者重新定义、追加属性和方法等。
    **

    使用要点:

    1.Java是单继承(一个子类只能有一个父类),没有多继承
    2.java中类没有多继承,接口有多继承。
    3.子类继承父类,得到父类的全部属性和方法(除了父类构造方法)
    4.若定义一个类时,没有调用extends,则父类是:java.lang.Object

    public class Person/*extends object*/ {//父类
        String name;
        int height;
    
        public void rest() {
            System.out.println("休息");
        }
    
        public static void main(String[] args) {
            Student w = new Student("zhangsan",180,60);
            System.out.println(w instanceof Person);
        }//instanceof 的使用,
    }
    
    class Student extends Person {//子类,继承了父类的属性和方法
        //   int id;
        //  String name;
    
        int score;
        // public void rest() {
        //      System.out.println("休息");
        //   }
    
        public void study() {
            System.out.println("学习" + this.name);
        }
    
        Student(String name, int height, int score) {
            this.name = name;
            this.height = height;
            this.score = score;
        }
    }
    

    instanceof 运算符

    instanceof是二元运算符,左边是对象,右边是类。当对象是右面类或子类创建的对象时,返回true,否则false。如上代码。
    **

    方法的重写(override):

    子类通过重写父类的方法
    方法重写的三个要点:
    1."==" 方法名、形参列表相同
    2."<=" 返回值类型和声明异常类型,子类小于等于父类(如:父类是person,子类不能是object)
    3.">=" 访问权限(如:public),子类大于等于父类

    package Test;
    
    import org.w3c.dom.ls.LSOutput;
    
    public class TestOverride {//重写是子类通过重写父类的方法。
        public static void main(String[] args) {
            Vehicle v1 = new Vehicle();
            Vehicle v2 = new Vehicle();
            Vehicle v3 = new Vehicle();
            v1.run();
            v2.run();
            v3.run();
            v2.stop();
            v3.stop();
        }
    }
    
    class Vehicle {//交通工具类
        public void run() {
            System.out.println("跑。。。");
        }
    
        public void stop() {
            System.out.println("停止不动");
    
        }
    }
    
    class Horse extends Vehicle{//马也是交通工具
        public void run(){ //重写父类方法
            System.out.println("四蹄翻飞");
        }
    }
    
    class Plane extends Vehicle{
        public void run(){//重新定义父类方法
            System.out.println("天上飞");
        }
        public void stop(){
            System.out.println("空中不能听");
        }
    }
    

    final关键字

    final关键字作用:

    修饰变量:被他修饰的变量不可改变,一但赋了初始值,就不能重新赋值。
    修饰方法:该方法不可被子类重写。但可以被重载。
    修饰类:修饰类不能被继承

    继承和组合

    is a用继承,如:Student is a person;has a 用组合,如:笔记本和芯片的关系
    “组合”的核心是“将父类对象作为子类的属性”,然后,“子类通过调用这个属性来获得父类的属性和方法。

    package Test;
    
    public class Test {
        public static void main(String[] args) {
            Student s =new Student("高淇",172,"Java");
             s.person.rest();//s.rest()
    
        }
    }
    
    class Person{
        String name;
        int height;
        public void rest(){
            System.out.println("休息一会");
        }
    }
    
    class Student /*extends Person*/{
       Person person = new Person();
        String major;
    
        public Student(String name,int height,String major){
           //天然拥有父类的属性
            this.person.name=name;// this.name = name;
            this.person.height=height;//this.height = height;
            this.person.rest();
            this.major=major;
        }
            }
    

    Object类

    Object是所有Java类的根基类,在类声明中未使用extends关键字指明的父类,则默认继承Object类。
    除了构造方法之外的所有的属性和方法都被继承。但是不是所有的都能使用。

    结构试图快捷键 command+7 看源码 command+左键
    常见字符串:

    toString 方法

    Object 类中定义public String to String()方法,返回值是String类型。
    public String toString(){
    return
    }

    ==和equals方法

    "=="代表双方是否相同,如果是基本类型则表示相等的值,如果是引用类型则表示地址相等则为同一个对象,否则表示不同。
    自动生成构造器、get、set方法、equal等。快捷键:control+return

    super 关键字

    super 含义可以看作是 直接父类对象的引用

    封装(encapsulation)

    封装是面向对象三大特征之一,对于程序合理的封装让外部调用更方便,更利于协作,同时,对于实现者来说也更容易修正和改版代码。

    作用和含义

    程序设计追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合是仅暴露少量的方法给外部使用,尽量方便外部调用。

    优点

    1. 提高代码安全性
    2. 提高代码复用性
    3. “高内聚”:封装细节,便于修改内部代码,提高维护性
    4. “低耦合”:简化外部调用,便于调用者使用,便于扩展和协作

    封装—使用访问控制符

    关于Protected的两个细节

    若父类和子类在同一个包中,子类可以访问父类的Protected成员,也可以访问父类对象的Protected成员
    若子类和父类不在同一个包中,子类可访问父类的Protected成员,不能访问父类对象的Protected成员

    封装的使用细节

    简单规则:

    1. 属性一般使用private访问权限
    2. 属性私有后,提供相应get/set方法来访问相关属性,通常用public修饰,以提供属性的赋值与读取操作(boolean变量get方法是is开头)
    3. 方法:一些只用于本地的类的辅助性方法可以使用private修饰,希望其他类调用的方法用public

    注意:

    引入get和set方法, set是设置,而get是获取,这两个方法是对数据进行设置和获取用的。而且,在类中使用set和get方法时,都是在set和get后面跟上一些特定的词来形成特定意思的方法名,比如set xxx()和get xxx(),表示设置xxx和获取xxx。(快捷键 control+return)

    多态

    概念:多态指的是同一方法调用,由于对象不同可能会有不同的行为。

    多态的要点

    1. 多态是方法的多态,不是属性的多态(多态与属性无关)
    2. 多态存在的3个必要条件:继承,方法重写,父类引用指向子类对象
    3. 父类引用指向子类对象后,用该父类调用子类重写的方法,多态就出现了
    package com.bjsxt.polymophism;
    
    public class Animal {
        public void shout(){
            System.out.println("叫了一声");
        }
    }
    //独立的类
    
    class Dog extends Animal{
        @Override
        public void shout() {
            System.out.println("汪汪汪");
        }
    }
    
    class Cat extends Animal{
        @Override
        public void shout() {
            System.out.println("喵喵喵");
        }
    }
    class  Tiger extends Animal{
        @Override
        public void shout() {
            System.out.println("wawaa");
        }
    }
    
    package com.bjsxt.polymophism;
    
    public class Test {
        static void animalCry(Animal a) {
            a.shout();//多态!!!
        }
    
        public static void main(String[] args) {
            //创建对象
            Dog d = new Dog();
            animalCry(d);//animal a =d ;父类引用指向子类对象
            animalCry(new Cat());//animal a =new Cat();父类引用指向子类对象
            animalCry(new Tiger());
        }
    }
    

    对象的转型

    父类引用指向子类对象,我们称为向上转型,属于自动转换。
    向上转型后的父类引用变量,只能调用它编译类型的方法,不能调用它运行时的方法。这时,我们就需要进行类型的强制转换,称之为向下转型!

    //测试类型的转换
            Animal a = new Dog();//向上类型转换,自动的
            Animal b = new Cat();
            a.shout();
           // a.seeDoor();需要强转
            Dog d2 =(Dog) a;//强制类型转化,向下类型转换,父类转子类
            d2.seeDoor();//只能调用它编译类型的方法,不能调用它运行时类型的方法,这时需要强转,称为向下转型!
    
            Cat c4 =(Cat) b;//
            c4.catchMouse();
    
    
            Cat c3 =(Cat) a;//java.lang.ClassCastException(可以编译,不可以执行,类型转换错误)
            c3.catchMouse();
        }
    }
    

    抽象方法—抽象类

    抽象方法

    使用abstract修饰方法,没有方法体,只有声明。定义的是一种规范。就告知子类必须给抽象方法提供具体实现

    抽象类

    包含抽象方法的类就是抽象类。通过abstract方法定义规范,然后要求子类必须定义具体实现。通过抽象类,我们可以做到严格限制子类的设计,使得子类之间更加通用

    package com.bjsxt.abstractClass;
    
    public abstract  class Student {
        private String name;//普通的属性和方法不受影响
        abstract public void study();//定义完抽象方法,类也变成抽象类
        abstract  public void exam();//抽象类方法必须由子类来实现
    //创建方法,跟抽象类无关
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    //构造方法
        public Student(String name) {
            this.name = name;
        }
        //无参构造器 (只要某个类是父类,则就加一个无参构造器)
        Student(){
            
        }
    }
    
    package com.bjsxt.abstractClass;
    
    public class Test {
        public static void main(String[] args) {
            //Student s =new Student("ddd"); 抽象类不能创建对象
        Student s = new SxStu();//父类引用指向子类对象
            s.study();
            s.exam();
        }
    }
    class SxStu extends Student{
    
        @Override
        public void study() {
            System.out.println("好好学习!!!");
        }
    
        @Override
        public void exam() {
            System.out.println("考100分!!");
    
        }
    }
    

    使用要点

    1. 抽象方法的类只能定义抽象类
    2. 抽象不能实例化,(抽象类)不能用new来创建对象
    3. 抽象类可包含 属性、方法、构造方法。但构造方法不能用new实例,只能被子类调用
    4. 抽象类只能用来继承
    5. 抽象方法必须被子类来实现

    接口(interface)的实现

    接口本质就是规范,定义的一组规则,是面向对象的精髓

    三个类的区别

    • [ ] 普通类:具体实现
    • [ ] 抽象类:具体实现,规范(抽象方法)
    • [ ] 接口:规范(jdk8 以后可加特殊的方法)

    接口的详细说明

    • [ ] 访问修饰符:只能是public或者默认
    • [ ] 接口名:和类名采用相同的命名机制
    • [ ] extends:接口可以多继承
    • [ ] 常量:接口中的属性只能是常量,总是public static final,不写也可以
    • [ ] 方法:接口中的方法只能是public abstract,省略的话,也是public abstrct

    要点

    • [ ] 子类通过implements来实现接口中的规范
    • [ ] 接口不能创建实例,但可用于声明引用对象变量类型
    • [ ] 一个类实现接口,必须实现接口中的所有方法,并且这些方法只能是public
    • [ ] jdk1.8(不含8)之前,接口中只能包含静态常量、抽象方法、不能是普通属性、构造方法和普通方法
    • [ ] jak1.8(含8)之后,接口中包含普通静态方法和默认方法(拓展方法)
    package com.bjsxt.testInterface;
    
    /**
     * 这时一个飞行器的接口
     */
    public interface Volant {
        /**
         * 表示飞行器在地球上的最高高度,单位是:公里
         */
        /*public static final */ int MAX_HIGHT = 100;
    
        /**
         * 飞行器方法,飞行器可以起飞
         */
        /* public abstract */void fly();
    
        /**
         * 可以让飞行器停止,若在空中悬停,如果在地上则停止
         */
        void stop();
    }
    
    /**
     * 善良接口
     */
    interface Honest {
        void helpOther();
    }
    
    package com.bjsxt.testInterface;
    
    public class SuperMan implements Volant,Honest{//接口中的所有方法必须实现,用英文逗号隔开
        @Override
        public void fly() {
            System.out.println("横着飞");
        }
    
        @Override
        public void stop() {
            System.out.println("竖着停");
        }
    
        @Override
        public void helpOther() {
            System.out.println("哪里call,飞哪里");
        }
    
        public static void main(String[] args) {
            SuperMan m1 =new SuperMan();//或者写成Volant m1 =new SuperMan
            m1.fly();//无需修改,fly()属于Volant 类
            m1.helpOther();//这里则需要强转 Honest h=(Honest) m1;
    
        }
    }
    

    默认方法

    默认方法和抽象方法的区别是抽象方法必须要实现,默认方法不是。作为替代方式,接口可以提供默认方法的实现,所以这个接口的实现类都会通过继承得到这个方法

    interface  A{
    default void moren(){//必须加default
        System.out.println("我是接口A中的默认方法!");
    }
    }
    
    class Test_A implements A{
        @Override
        public void moren() {
            System.out.println("Test_A");
        }
    }
    public class Test {
        public static void main(String[] args) {
            A a =new Test_A();
            a.moren();
        }
    }
    

    静态方法

    如果子类中定义相同的静态方法,那就是我完全不同的方法了,直接从属于子类,可以通过子类名直接调用

    public class Testjing {
        public static void main(String[] args) {
            B.staticMethod();
            Test_B.staticMethod();
        }
    }
    
    interface B{//接口属于特殊的类
     public static void staticMethod(){
         System.out.println("A.staticMethod");
     }   
    }
    
    class Test_B implements B{//创建子类
        public static void staticMethod(){
            System.out.println("Test_B.staticMethod");
        }
    }
    

    接口多继承

    interface B{
        void test0b();
    }
    
    interface C{
        void test0c();
    }
    /**接口可以多继承,接口D继承B和C*/
    interface D extends B,C{
        void test0d();
    }
    
    public class Test0 implements D{
        @Override
        public void test0b() {
    
        }
    
        @Override
        public void test0c() {
    
        }
    
        @Override
        public void test0d() {
    
        }
    }
    

    String 类和常量池

    1. 全局字符串常量池(String  Pool)
    2. class文件常量池(Class Constant Pool)
    3. 运行时常量池(Runtime Constant Pool)

    字符串相等判断(以后一般判断字符串值是否相等,使用equals())

    public class Test1 {
        public static void main(String[] args) {
            String str1 =new String("abcdef");
            String str2 ="abcdef";
            System.out.println(str1==str2);
            System.out.println(str2.equals(str1));//比较我们两个字符串对象是不是一样的
        }
    }
    

    String类常用方法

    char charArt(index) //  返回字符串中第index个字符
    boolean equals(String other) //字符串与other相等,返回true,否则返回false
    boolean equalsIgnoreCase(String other)//字符串与other(忽略大小写)返回true,否则返回false
    int indexOf(String str) //返回从头开始查找str在字符串索引中的位置,未找到str,返回-1
    lastIndexOf(String str) //返回从尾查找str在字符串索引中的位置,未找到,返回-1
    int length()// 返回字符串的长度
    String replace(char oldChar,char newChar)//返回新的字符串,替换
    boolean starWith(String prefix) //判断字符串以prefix 开始,返回true,否则返回false
    boolean endWith(String prefix) //判断以prefix结尾,返回true,否则返回false
    String subsring(int beginIndex)//返回一个新的字符串,从beginIndex到串尾
    String substring(int beginIdex,int endIdex) //返回一个新的字符串,从beginIndex到endIndex-1
    String toLowerCase() //返回一个新字符串,原始字符串所有大写改成小写
    String toUpperCase() //返回一个新字符串,原始字符串所有小写改成大写
    String trin()//返回一个新的字符串,去掉首尾空格
    
    //举例
    public class test03 {
        public static void main(String[] args) {
            System.out.println("abcdef".charAt(5));//f
            System.out.println("abcdef".equals("abcdef"));//true
            System.out.println("ab".equalsIgnoreCase("AB"));//true
            System.out.println("abcde".indexOf("cd")); //第2位
            System.out.println("abcde".lastIndexOf("d"));//第3位
            System.out.println("abcde".length());//5
            System.out.println("abcde".replace("bc","BC"));//aBCde
            System.out.println("abcde".startsWith("bc"));//false
            System.out.println("abcde".endsWith("de"));//true
            System.out.println("abcde".substring(1));//bcde
            System.out.println("abcde".substring(2,4));//cd
            System.out.println("abcde".toUpperCase());//ABCDE
            System.out.println("aBCDe".toLowerCase());//abcde
            System.out.println("   a b   ".trim());//a b
        }
    }
    

    内部类

    内部类是把一个类放在另一个类的内部定义。
    内部类只是一个编译时概念,一旦编译成功,就会成为完全不同的两个类。

    内部类的作用:

    内部类提供更好的封装,只能让外部类直接访问,不允许同一个包中的其他类直接访问。
    内部类可以直接访问外部类的私有属性,内部类被当成其他外部类的成员,但外部类不能访问内部类

    //非静态内部类
    //外部类
    public class Outer1 {
        private int age = 10;
    
        private void show() {
            System.out.println("要你好看");
        }
    
        //内部类
        public class Inner1 {
            private String name = "tom";
            private int age = 20;
    
            public void showInner() {
                System.out.println("Inner.showInner");
                System.out.println(age);
                System.out.println(Outer1.this.age);//当外部类属性和内部类属性发生重名时,可以通过:Outer.this.成员名
                show();//内部类可以直接使用外部类的成员
            }
        }
    
        public static void main(String[] args) {
            Outer1.Inner1 inn01 = new Outer1().new Inner1();
            inn01.showInner();
    //另一种写法
            Outer1 out2 = new Outer1();
            Inner1 inn02 = out2.new Inner1();
            inn02.showInner();
        }
    }
    
    //静态内部类
    
    class Outer2 {
        private int a =10;
        private  static  int b =20;
        //相当于外部类的一个静态成员
    
        static class Inner{
            public void test(){
               // System.out.println(a); //静态内部类不能访问外部非静态普通属性
                System.out.println(b);//静态内部类可以访问外部类静态属性
            }
        }
            }
    public class jingtai {
        public static void main(String[] args) {
            //通过new外部类名.内部类名()来创建内部对象
            Outer2.Inner inner =new Outer2.Inner();
            inner.test();
        }
    }
    
    //匿名内部类
    //匿名内部类测试
    public class TestAnonymousInnerclass {
        public void test(A a){
            a.run();
        }
    
        public static void main(String[] args) {
            TestAnonymousInnerclass tai =new TestAnonymousInnerclass();
            tai.test(new AA());
    
            tai.test(new A() {
                @Override
                public void run() {
                    System.out.println("TestAnonymousInnerclass.run");
                }
            });
        }
        }
      //有名字,可以反复使用
    class AA implements A{
    
        @Override
        public void run() {
            System.out.println("AA.run");
        }
    }
    
    interface A{
        void run();
    }
    
    悲观者正确,乐观者成功
  • 相关阅读:
    Slf4j框架的用法
    常用框架介绍
    Spring整合Kafka(Spring-Kafka)
    Java并发容器
    kafka多线程消费
    kafka简介
    kafka-clients介绍
    windows搭建kafka
    rocketmq-client使用
    Window搭建部署RocketMQ
  • 原文地址:https://www.cnblogs.com/freebule/p/14462988.html
Copyright © 2020-2023  润新知