JavaStudy—B站韩顺平(接口+内部类)

发布于:2022-12-15 ⋅ 阅读:(479) ⋅ 点赞:(0)

(八)接口

1.基本介绍

1.1快速入门

//定义一个接口
public interface UsbInterface {
    //规定接口的相关规定
    public void start();
    public void stop();
}
//Phone 类 实现 UsbIterface接口
//解读 1. 即 Phone 类需要实现 UsbInterface 接口 规定/声明的方法
public class Phone implements UsbInterface{ //实现接口
    @Override
    public void start() {
        System.out.println("手机开始工作");
    }

    @Override
    public void stop() {
        System.out.println("手机停止工作");
    }
}
// Camera类 实现 UsbIterface接口
public class Camera implements UsbInterface{//实现接口,就是把接口方法实现
    @Override
    public void start() {
        System.out.println("相机开始工作");
    }

    @Override
    public void stop() {
        System.out.println("相机停止工作");
    }
}
//Computer  使用接口
public class Computer {
    //编写一个方法
    public void work( UsbInterface usbInterface){
        usbInterface.start();
        usbInterface.stop();

    }
}
public class Interface01 {
    public static void main(String[] args) {
        //创建手机相机对象
        Phone phone = new Phone();
        Camera camera = new Camera();
        //创建计算机
        Computer computer = new Computer();
        computer.work(phone);//把手机接入到计算机
        System.out.println("===============");

        computer.work(camera);//吧相机接入到计算机
    }
}

1.2基本介绍

​ 接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。

语法:

在这里插入图片描述

深入讨论(代码演示):

public interface DBInterface {
    public void connect();//开始了解
    public void close();//关闭连接
}
public class OracleDB implements DBInterface{  //实现接口,重写方法
    @Override
    public void connect() {
        System.out.println("OracleDB 开始连接");
    }

    @Override
    public void close() {
        System.out.println("OracleDB 关闭连接");
    }
}
public class MysqlDB implements DBInterface{ //实现接口
    @Override
    public void connect() {
        System.out.println("MysqlDB 开始连接");
    }

    @Override
    public void close() {
        System.out.println("MysqlDB 关闭连接");
    }
}
public class Interface03 {
    public static void main(String[] args) {
        MysqlDB mysqlDB = new MysqlDB();
        con(mysqlDB);

        OracleDB oracleDB = new OracleDB();
        con(oracleDB);
    }

    public static void con(DBInterface dbInterface){  
        dbInterface.connect();
        dbInterface.close();
    }
}

1.3注意事项和细节

  1. 接口不能被实例化

  2. 接口中所有的方法都是public方法,接口中抽象方法,可以不用abstract修饰
    在这里插入图片描述

  3. 一个普通类实现接口,就必须实现该接口的所有方法
    在这里插入图片描述
    解释:Class ‘A’ must either be declared abstract or implement abstract method ‘cry()’ in ‘IA’ (类“A”必须声明为抽象或在“IA”中实现抽象方法“cry()”)

  4. 抽象方法去实现接口时,可以不实现接口的抽象方法
    在这里插入图片描述

  5. 一个类可以实现多个接口

在这里插入图片描述

  1. 接口中的属性只能是final ,而且是public static final 修饰符

在这里插入图片描述
在这里插入图片描述
7. 接口属性的访问形式 :接口名.属性名

  1. 接口不能继承其他的类,但是可以继承多个其他接口

在这里插入图片描述

  1. 接口的修饰符只能是 public 和默认,这点和类的修饰符是一样

总计:

在这里插入图片描述
在这里插入图片描述

2. 课堂练习

  1. 输出的类容
public class InterfaceExcrcise01 {
    public static void main(String[] args) {
        BBB bbb = new BBB();
        System.out.println(bbb.a);
        System.out.println(AAA.a);
        System.out.println(BBB.a);
    }
}
interface AAA{
    int a = 23;
}
class BBB implements AAA{
}

在这里插入图片描述

3.实现接口 vs继承类

  1. 接口和继承解决的问题不同

    继承的主要价值在于 :解决代码的可复用性和耦合性;

    接口的主要价值在于:设计 设计好各种规范(方法),让其他类去实现这些方法,即变得更加得灵活。

  2. 接口比继承更加灵活
    接口比继承更加灵活,继承是满足is~a的关系,而接口只需满足like-a的关系。

  3. 接口一定程度上实现代码解耦。[即接口规范性+动态绑定机制]

    举例:

    小猴子继承于Monkey 拥有父类非私有的属性和方法,但是小猴子想飞或者游泳。这时候可以把飞,和游泳定义为接口,这时小猴子就可以去实现(implement)这两个接口达到飞和游泳的技能。(这相当于后天学习)

在这里插入图片描述

public class ExtendsVsInterface {
    public static void main(String[] args) {
        LittleMonkey wuKong = new LittleMonkey("悟空");
        wuKong.climbing();
        wuKong.swimming();
    }
}

//小结:当子类继承了父类。就自动的拥有父类的功能
//如果子类需要扩展功能,可以通过实现接口的方式扩展
//可以理解 实现接口 对Java 单继承机制的一种补充
class Monkey {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Monkey(String name) {
        this.name = name;
    }

    public void climbing() {
        System.out.println(name + " 会爬树");
    }
}

interface FishAble {
    void swimming();
}

interface BirdAble {
    void fly();
}

class LittleMonkey extends Monkey implements FishAble, BirdAble {
    public LittleMonkey(String name) {
        super(name);
    }

    @Override
    public void swimming() {
        System.out.println(getName() + " 经过学习会游泳");
    }

    @Override
    public void fly() {
        System.out.println(getName() + "经过学习会飞翔");
    }
}

4.接口的多态特性

在这里插入图片描述

public class InterfacePolyParameter {
    public static void main(String[] args) {
        //接口的多态
        //接口类型的变量 if01 可以指向 实现了IF接口的对象实例
        IF if01 = new Monster();
        if01 = new Car();
        //继承体现的多态
        //父类类型的变量 a 可以指向 继承了AAAA的对象实例
        AAAA a = new BBBB();
        a = new CCCC();
    }
}
interface IF{}//接口
class Monster implements IF{}//实现类Monster
class Car implements IF{}//实现类Car

class AAAA{}//父类
class BBBB extends AAAA{}//子类BBBB
class CCCC extends AAAA{}//子类CCCC

多态数组 -> 接口类型数组

记一记:(instanceof)判断对象运行类型返回值true/false

public class InterfacePolyArr {
    public static void main(String[] args) {
        //多态数组 -> 接口类型数组
        Usb[] usb = new Usb[2];
        usb[0] = new Phone_();
        usb[1] = new Camera_();
        /*给 Usb 数组中,存放 Phone 和 相机对象,Phone 类还有一个特有的方法 call(),
        请遍历 Usb 数组,如果是 Phone 对象,除了调用 Usb 接口定义的方法外,
        还需要调用 Phone 特有方法 call */
        for (int i = 0; i < usb.length; i++) {
            usb[i].work();;//动态绑定..
            // 和前面一样,我们仍然需要进行类型的向下转型
            if (usb[i] instanceof Phone_){//判断他的运行类型是 Phone_
                ((Phone_) usb[i]).call();
            }
        }
    }
}
interface Usb{
    void work();
}

class Phone_ implements Usb{

    @Override
    public void work() {
        System.out.println("手机在工作。。。");
    }
    public void call(){
        System.out.println("手机可以打电话");
    }
}
class Camera_ implements Usb{

    @Override
    public void work() {
        System.out.println("相机在工作。。。");
    }
}

接口存在多态传递现象。InterfacePolyPass.java

public class InterfacePolyPass {
    public static void main(String[] args) {
        //接口类型的变量可以指向,实现了该接口的类的对象实例
        IG ig = new Teacher();
        //如果IG继承了IH 而Teacher实现了IG接口
        //那么也相当于 Teacher实现了IH接口
        //这就是所谓得接口多态传递现象
        //(这和子类继承父类,父类继承了爷爷类一样 爷爷类就可以指向子类了)
        IH ih = new Teacher();
    }
}
interface IG extends IH{}
interface IH{}
class Teacher implements IG{}

5.课堂练习 InterfaceExercise02.java

在这里插入图片描述
在这里插入图片描述

public class InterfaceExercise02 {
    public static void main(String[] args) {
        new Cc().pX();
    }
}
interface Aa{
    int x = 0;
    //等价 public static final int x = 0;
}
class Bb{
    int x =1;
    //普通变量
}

class Cc extends Bb implements Aa{
    public void pX(){
        //System.out.println(x); //错误,原因:x变量指向不明确
        //可以明确的指定 x
        // 访问接口的 x 就使用 A.x
        // 访问父类的 x 就使用 super.x
        System.out.println(Aa.x  + " " + super.x);
    }
}

(九)内部类

1.基本介绍

​ 一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(Outer class)。是类的第五大成员(属性,方法,构造器,代码块,内部类)。内部类最大的特点是可以直接访问私有属性,并且可以体现类与类之间的包含关系。

1.1基本语法

在这里插入图片描述

public class InnerClass01 { 
    //外部其他类 
    public static void main(String[] args) {
    }
}
class Outer { //外部类 
    private int n1 = 100;//属性 
    public Outer(int n1) {//构造器 
        this.n1 = n1; 
    }
    public void m1() {//方法 
        System.out.println("m1()"); 
    }
    {//代码块
        System.out.println("代码块..."); 
    }
    class Inner { //内部类, 在 Outer 类的内部
    }
}

2.内部类的分类

  1. 定义在外部类的局部位置上(比如方法内)

    • 局部内部类(有类名)
    • 匿名内部类(没有类名 重点!)
  2. 定义在外部类的成员位置上:

    • 成员内部类(没有static修饰)
    • 静态内部类(使用static修饰)

3.局部内部类

3.1局部内部类的使用

**说明:**局部内部类是定义在外部类的局部位置 通常在方法中

  1. 可以直接访问外部类所有成员,包含私有的
  2. 不能添加访问修饰符,因为他的地位是一个局部变量。局部变量不能用修饰符修饰,大师可以使用final修饰,因为局部变量也可以用final
  3. 作用域:仅仅在定义他的方法或者代码块中
  4. 局部内部类可以直接访问外部类成员,(就比如下面外部类n1和m2())
  5. 外部类在方法中,可以创建内部类对象实例,然后调用方法即可(必须在作用域类)

记住:(1) 局部内部类定义在方法中/代码块

(2)作用域在方法体或者在代码块中

(3)本质认识一个类

  1. 外部类不能访问局部内部类(因为局部内部类的地位是一个局部变量)

  2. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问 System.out.println(“外部类的n2:” +外部类名.this.成员);

    实例:

public class LocalInnerClass {
    public static void main(String[] args) {
        Outer02 outer02 = new Outer02();
        outer02.m1();
    }
}

class Outer02 {
    private int n1 = 10;
    private int n2 = 20;
    public void m2() {
        System.out.println("m2");
    }

    public void m1() {
        //1.局部内部类是定义在外部类的局部位置 通常在方法中
        //3.不能添加访问修饰符,因为他的地位是一个局部变量。局部变量不能用修饰符修饰,但是可以使用final修饰
        //4.作用域:仅仅在定义他的方法或者代码块中
        class Inner {//局部内部类(本质任然是一个类)
            String name = "小南门";
            private int n1 = 200;

            //2.可以直接访问外部类所有成员,包含私有的
            public void f1() {
                //5.局部内部类可以直接访问外部类成员,就比如下面外部类n1和m2()
                //7.如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成
                //员,则可以使用(外部类名.this.成员)去访问
                // System.out.println("外部类的n2:" +外部类名.this.n2);
                //解读:Outer.this 本质就是外部类的一个对象,即那个对象调用了m1(),Outer.this就是那个对象
                System.out.println("n1 =" + n1);
                m2();
                System.out.println(Outer02.this.n1);
            }
        }
        //6.外部类在方法中,可以创建Inner02对象实例,然后调用方法即可
        Inner inner = new Inner();
        inner.f1();
    }
}
3.2扩充:什么是局部变量和全局变量:
  1. 局部变量:
   局部变量的定义:定义在方法中的变量都是局部变量(main方法也是方法,所以定义在main方法中的变量也是局部变量)。
  生存时间:局部变量的生存时间和方法的生存时间一致,调用该方法声明该局部变量并初始化的时,该局部变量被创建并分配内存空间;直到该方法调用结束局部变量也就结束了;
	是否需要初始化:局部变量在使用前必须进行初始化,系统默认不会对局部变量进行初始化数据操作,如果局部变量在使用前没有进行初始化则会在编译器报错;如果局部变量进行了声明没有进行初始化,但是也一直没有被使用的话编译也是不会报错的;(局部变量使用前必须初始化话)
 创建位置: 局部变量是创建在栈内存中的;
  1. 全局变量:

    2.1 非静态全局变量:

       非静态全局变量的定义:非静态全局变量都是定在类中,是类的成员变量或者说是成员属性属于类的一部分(或者说是对象的一部分);
       生存时间:非静态全局变量加载在堆内存中,随着声明初始化而创建,随着对象消亡而消亡;
       是否需要初始化:全局变量都是不需要被强制初始化的,系统都会默认根据其数据类型进行默认赋值;但是建议在声明时都进行初始化操作;
       创建位置:创建在堆内存中,因为非静态的全局变量数对象的成员变量是对象的一部分;
    

    2.2静态全局变量:

       静态全局变量的定义:静态的类成员变量;
       生存时间:静态全局变量随着类的字节码文件加载而加载产生,随着字节码文件的消失而消失,生存时间比类的对象还要长;
       是否初始化:凡是全局变量都是可以不要初始化的,静态变量也是一样,系统会自动根据其数据类型进行赋默认值,但是建议变量在声明时都进行初始化;
       创建位置:静态变量时存在于堆内存中的,所以静态全局变量也是存在于堆内存中的;
    

4.匿名内部类

4.1匿名内部类的使用
  1. 本质是类 2.内部类 3. 该类没有名字 4.同时还是一个对象

    说明:匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名

在这里插入图片描述

代码演示:

基于接口的匿名内部类:

/**
 * 演示匿名内部类
 */
public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}

class Outer04 {//外部类
    private int n1 = 10;//属性

    public void method() {//方法
        //基于接口的匿名内部类
        // 老韩解读
        // 1.需求: 想使用 IA 接口,并创建对象
        // 2.传统方式,是写一个类,实现该接口,并创建对象
        //3.需求是:Tiger类只是用一次,后面不在使用
        //4.可以使用匿名内部类来简化开发
        //5.tiger1 的编译类型 ? IA
        //6.tiger1 的运行类型 ? 就是匿名内部类 Outer04$1
        /*
        看底层 会分配 类名 Outer04$1
        class Outer04$1 implement IA{
         @Override
         public void cry() {
            System.out.println("老虎哭了");
    }
}
         */
        //7.jdk底层在创建内部类 Outer04$1时,就马上创建了 Outer04$1实例,并且把地址返回给tiger1
        //8.匿名内部类使用一次,就不能在使用 但是对象还在
        IA tiger1 = new IA() {
            @Override
            public void cry() {
                System.out.println("老虎叫了");
            }
        };
        tiger1.cry();
        System.out.println("tiger1 = " + tiger1.getClass());//查看运行类型
        Tiger tiger = new Tiger();
        tiger.cry();

    }

}

interface IA {  //接口
    void cry();
}

class Tiger implements IA {

    @Override
    public void cry() {
        System.out.println("老虎哭了");
    }
}

class Father {//类

    public Father(String name) {//构造器
    }

    public void test() {
    }
}

基于类的匿名内部类:

        //演示基于类的匿名内部类
        // 分析
        // 1. father 编译类型 Father
        // 2. father 运行类型 Outer04$2
        // 3. 底层会创建匿名内部类
            /*
        class Outer04$2 extends Father{//类
        public Father(String name) {//构造器
        }
        public void test() {
        }
}
         */
        //4.同时也直接返回了匿名内部类Outer$2的对象
        //5.注意("jack")参数会传递给 构造器
        Father father = new Father("jack"){
            @Override
            public void test() {
                System.out.println("匿名内部类重写了test()");
            }
        };

        System.out.println("father运行类型" + father.getClass());//Outer04$2
        father.test();

        //基于抽象类的匿名内部类
        Animal animal = new Animal(){

            @Override
            void eat() {
                System.out.println("小狗吃饭");
            }
        };
        animal.eat();
    }

}

class Father {//类
    public Father(String name) {//构造器
        System.out.println("接受到name = " + name);
    }
    public void test() {
    }
}
abstract class Animal{
    abstract void eat();
}

在这里插入图片描述

  1. 可以直接访问外部类的所有成员,包括私有的
  2. 不能添加访问修饰符,因为他的地位就是一个局部变量。
  3. 作用域:仅仅在定义他的代码块或者方法中
  4. 外部其类不能访问匿名内部类(因为 匿名内部类地位是一个局部变量)
  5. 如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用 (外部类名.this.成员)去访问
public class AnonymousInnerClassDetail01 {
    public static void main(String[] args) {
        Outer05 outer05 = new Outer05();
        outer05.f1();
        System.out.println("main 中outer05的hashcode = " + outer05);
    }
}

class Outer05 {
    private int n1 = 9;

    public void f1() {
        //创建一个基于类的匿名内部类
        //4.不能添加访问修饰符,因为他的地位就是一个局部变量。
        //5.作用域:仅仅在定义他的代码块或者方法中
        //6.外部其类不能访问匿名内部类(因为 匿名内部类地位是一个局部变量)
        Person person = new Person() {
            private int n1 = 11;

            @Override
            public void hi() {
                //4.可以直接访问外部类的所有成员,包括私有的
                //如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,
                //默认遵循就近原则,如果想访问外部类的成员,则可以使用 (外部类名.this.成员)去访问
                System.out.println("匿名内部类重写了hi()  n1 = " + Outer05.this.n1);
                //Outer.this 就是调用 f1的对象
                System.out.println("Outer05.this的hashcode = " + Outer05.this);
            }
        };
        person.hi();//动态绑定   运行类型时Outer05$1
        //3.也可以直接调用,匿名内部类本身也是返回对象
        //class 匿名内部类 extends Person {} 
        new Person() {
            @Override
            public void hi() {
                System.out.println("匿名内部类重写了hi()  new Person");
            }

            @Override
            public void ok(String str) {
                super.ok(str);
            }
        }.ok("jack");
    }
}


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

    public void ok(String str) {
        System.out.println("Person ok()  " + str);
    }
}
4.2匿名内部类最佳实战
  • 当作实参直接传递,简洁高效
public class InnerClassExercise01 {
    public static void main(String[] args) {
        //当作实参直接传递,简洁高效
        f1(new IL() {
            @Override
            public void show() {
                System.out.println("这是一副名画");
            }
        });
        //传统方式
        Picture picture = new Picture();
        f1(picture);
    }
    //静态方法,形参是接口类型
    public static void f1(IL il){
        il.show();
    }
}
interface IL{//接口
    void show();
}
//类->实现 IL => 编程领域 (硬编码)
class Picture implements IL{
    @Override
    public void show() {
        System.out.println("这是一副名画");
    }
}
4.3匿名内部类课堂练习
/*
1.有一个铃声接口Bell,里面有个ring方法。
(右图)
2.有一个手机类Cellphone,具有闹钟功能
alarmclock,参数是Bell类型(右图)
3.测试手机类的闹钟功能,通过匿名内部类(对
象)作为参数,打印:懒猪起床了
4.再传入另一个匿名内部类(对象),打印:
小伙伴上课了
 */
public class InnerClassExercise02 {
    public static void main(String[] args) {
        CellPhone.alarmClock(new Bell() {
            @Override
            public void ring() {
                System.out.println("懒猪起床了");
            }
        });
        CellPhone.alarmClock(new Bell() {
            @Override
            public void ring() {
                System.out.println("懒猪上课了");
            }
        });
    }
}

interface Bell { //接口
    void ring();//抽象方法
}

class CellPhone {
    public static void alarmClock(Bell bell) {//形参时Bill接口类型
        bell.ring();//动态绑定
        };
    }

5.成员内部类的使用

说明:成员内部类是定义在外部类的成员位置,并且没有static修饰。有static称为静态内部类。

  1. 注意:成员内部类,是定义在外部类的成员位置上

  2. 可以添加任意的访问修饰符(public protected,默认 ,private),因为他的地位就是一个成员变量

  3. 作用l域MemberlnnerClass01,java和外部类的其他成员一样,为整个类体比如前面案例,在外部类的成员方法中创建成员内部类对象,再调用方法.

  4. 成员内部类–>访问–>外部类成员(比如:属性)[访问方式:直接访问]

  5. 外部类–访问—>成员内部类访问方式:创建对象,再访问

  6. 外部其他类–访问–>成员内部类 有两种方式

//第一种方式
//outer08.new Inner08();    相当与new Inner08() 当作是 outer08的成员
Outer08.Inner08 inner08 = outer08.new Inner08();
        inner08.say();
//第二种方式 在外部类中编写一个方法 可以返回Inner08对象
Outer08.Inner08 inner081 = outer08.getInner08();
        inner081.say();

public Inner08 getInner08(){
        return new Inner08();
    }

代码演示:

public class MemberInnerClass01 {
    public static void main(String[] args) {
        Outer08 outer08 = new Outer08();
        outer08.t1();

        //外部其他类,使用成员内部类的三种方式
        //第一种方式
        //outer08.new Inner08();    相当与new Inner08() 当作是 outer08的成员
        Outer08.Inner08 inner08 = outer08.new Inner08();
        inner08.say();
        //第二种方式 在外部类中编写一个方法 可以返回Inner08对象
        Outer08.Inner08 inner081 = outer08.getInner08();
        inner081.say();
    }
}

class Outer08 {//外部类
    private int n1 = 8;
    public String name = "张三";

    //1.注意:成员内部类,是定义在外部类的成员位置上
    //2.可以添加任意的访问修饰符(public protected,默认 ,private),因为他的地位就是一个成员变量
    public class Inner08 {//成员内部类
        private double sal = 9.99;
        private int n1 = 100;

        public void say() {
            //1.可以直接访问外部类的其他成员,包括私有的
            System.out.println(Outer08.this.n1 + name);

        }
    }

    public Inner08 getInner08() {
        return new Inner08();
    }

    //写方法
    public void t1() {
        //使用成员内部类
        //创建成员内部类的对象,然后使用相关的方法
        Inner08 inner08 = new Inner08();
        inner08.say();
        System.out.println(inner08.sal);
    }

6.静态内部类的使用

放在外部类的成员位置 使用static修饰

  1. 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

  2. 可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。

  3. 作用域:同其他的成员,为整个类体

  4. 静态内部类–访问–>外部类(比如:静态属性)[访问方式:直接访问所有静态成员]

  5. 外部类–访问–>静态内部类访问方式:创建对象,再访问

  6. 外部其他类,使用静态内部类 有两种方法

    //外部其他类,使用静态内部类
    //方式一
    //因为静态内部类,是可以直接通过类名访问(前提时满足访问权限)
    Outer10.Inner10 inner10 = new Outer10.Inner10();
    inner10.say();
    //方法二
    //编写一个方法,可以返回静态内部类的对象实例
    Outer10.Inner10 inner101 = outer10.getInner10();
    inner101.say();
    //静态,可以直接用类名点方法调用
     Outer10.Inner10 inner102 = new Outer10().getInner10();
     inner102.say();
    
  7. 如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问.

小结:

  1. 内部类有四种:局部内部类,匿名内部类,成员内部类,静态内部类

  2. 重点掌握匿名内部类

    new 类/接口(参数列表){

    //…

    }

    1. 成员内部类,静态内部类是放在外部类的成员位置,本质就是一个成员
public class StaticInnerClass01 {
    public static void main(String[] args) {
        Outer10 outer10 = new Outer10();
        outer10.m1();

        //外部其他类,使用静态内部类
        //方式一
        //因为静态内部类,是可以直接通过类名访问(前提时满足访问权限)
        Outer10.Inner10 inner10 = new Outer10.Inner10();
        inner10.say();
        //方法二
        //编写一个方法,可以返回静态内部类的对象实例
        Outer10.Inner10 inner101 = outer10.getInner10();
        inner101.say();
        //静态,可以直接用类名点方法调用
        Outer10.Inner10 inner102 = new Outer10().getInner10();
        inner102.say();
    }
}

class Outer10 { //外部类
    private int n1 = 10;
    private static String name = "张三";

    //Inner10 就是一个静态内部类
    //1.放在外部类的成员位置
    //2.使用static修饰
    //1.可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员
    //2.可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。
    //3.作用域:同其他的成员,为整个类体
    //4.静态内部类--访问-->外部类(比如:静态属性)[访问方式:直接访问所有静态成员]
    //5.外部类--访问-->静态内部类访问方式:创建对象,再访问
    //6.外部其他类,使用静态内部类 有两种方法
    //7.如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如
    //果想访问外部类的成员,则可以使用(外部类名.成员)去访问.
    static class Inner10 {
        private static String name = "覃波";
        public void say() {
            System.out.println(name);
            System.out.println(Outer10.name);
        }
    }
    public void m1(){//外部类--访问-->静态内部类访问方式:创建对象,再访问
        Inner10 inner10 = new Inner10();
        inner10.say();
    }
    public Inner10 getInner10(){
        return new Inner10();
    }
}

7.内部类练习

/**
 *写出输出结果
 */
public class InnerClassExercise03 {

}
class Test {//外部类
    public Test() {//构造器
        Inner s1 = new Inner();
        s1.a = 10;
        Inner s2 = new Inner();
        System.out.println(s2.a);
    }
    class Inner { //内部类,成员内部类
        public int a = 5;
    }
    public static void main(String[] args) {
        Test t = new Test();
        Inner r = t.new Inner();//5
        System.out.println(r.a);//5
   

我亦无他,惟手熟尔


网站公告

今日签到

点亮在社区的每一天
去签到