VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Java教程 >
  • 第六课-面向对象

什么是面向对象

  • java的核心思想就是面向对象
  • 两种编程思想
    • 面向过程思想(线性思维)
      • 步骤清晰简单,第一步做什么,第二步做什么
      • 面向过程适合处理一些较为简单的问题
    • 面向对象思想
      • 是一种分类的思维模式,思考解决问题需要哪些分类,然后对这些分类进行单独思考,最后,才对某个分类下的细节进行面向对象的思索.每个分类作为一个类(类是抽象的,例如人这一普遍概念,使用时,再把人这一普遍概念的共性对应到具体某一个人身上).
      • 面向对象适合处理复杂问题,适合多人协作,每人负责问题的一个分类的解决(类似于一个大任务分成各类小任务)
    • 注意:对于描述复杂事物,为了从宏观上把握,从整体上合理分析,需要使用面向对象的思路来分析整个系统.但是,具体到微观操作,仍然需要面向过程的思路去处理.
  • 面向对象编程(Object-Oriented Programming,OOP)
  • 面向对象编程的本质:以类的方式组织代码,以对象的方式组织(封装)数据
  • 抽象:把一类事物中的共性提取出来(例如学生都有学号,学号就是共性)
  • 面向对象三大特性
    • 封装:把数据包装起来,通过特定的接口进行访问
    • 继承:子类会默认继承父类当中已有的东西
    • 多态:就是同一个事物有多个形态,例如人分为白人黑人,人都有跑这一个动作,但黑人跑的比白人快
  • 从认识论的角度是先有对象后有类.对象是具体的事物;类是抽象的,是对对象的抽象
  • 从代码运行的角度考虑是先有类后有对象,类是对象的模板

方法回顾

public class Hello {
    public static void main(String[] args) {

    }

    /*
    修饰符 返回值类型 方法名(..){方法体}
     */
    // return 结束方法,返回一个结果
    // break只结束循环,后面语句可以继续执行
    public String sayHello() {
        return "Hello,world";
    }

    public void hello() {
        return;
    }

    public int max(int a, int b) {
        return a > b ? a : b;  //三元运算符
    }
}
package Demo;

// 学生类
public class Student {
    // 非静态方法
    public void say() {
        System.out.println("学生说话了");
    }
}
package Demo;

public class Demo01 {
    public static void main(String[] args) {
        // 实例化要调用的类
        // 对象类型 对象名=对象值;
        Student student = new Student();
        student.say();
    }
}
package Demo;

public class Demo01 {
    // 以下这种情况,b可以调用a,但a不可以调用b
    // 静态方法static和类一起加载
    public static void a() {
    }
    // 非静态方法需要在类实例化(new)之后才存在
    public void b() {
    }
}
package Demo;

// 值传递
// java都是值传递
public class Demo01 {
    public static void main(String[] args) {
        int a = 1;
        System.out.println(a);

        Demo01 demo = new Demo01();
        demo.change(a);
        System.out.println(a);
    }

    // 未返回任何值
    public void change(int a) {
        a = 10;
    }
}

package Demo;

// 引用传递,操作的是对象,本质还是值传递
public class Demo01 {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name);

        Demo01 demo = new Demo01();
        demo.change(person);
        System.out.println(person.name);
    }

    // 未返回任何值
    public void change(Person person) {
        // person是一个对象,而不是形参,person对象指向Person person = new Person();这是一个具体的人,可以改变名字(属性)
        person.name = "我的名字";
    }
}

// 一个类中只能有一个public类
// 定义一个Person类,有一个属性:name
class Person {
    String name;  // 默认值为null
}

类与对象的创建

类与对象的关系

  • 类是一种抽象的数据类型,是对某一类事物的整体描述/定义,但是不能代表某一个具体的事物
    • 例如:动物,植物,手机,电脑
    • 类是用来描述/定义某一类具体的事物应该具备的特点和行为
  • 对象是抽象概念的具体实例
    • 张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例
    • 能够展现出特点,展现出功能是具体的实例,而不是一个抽象的概念

创建与初始化对象

  • 使用new关键字创建对象

  • 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及类中的构造器的调用

  • 类的构造器也称为构造方法,是在进行创建对象的时候必须要调用,并且构造器有以下两个特点

    1. 必须和类的名字相同

    2. 必须没有返回类型,也不能写void

  • 构造器必须要掌握

package Demo;

// 学生类,一个类里面只能有属性和方法两种东西
public class Student {
    // 属性
    String name;
    int age;

    // 方法
    // this指的是当前类
    public void study() {
        System.out.println(this.name + "在学习");
    }
}
package Demo;

// 一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        // 类,抽象的,实例化
        // 类实例化后会返回一个自己的对象
        // student对象就是Student类的具体实例
        Student student1 = new Student();
        Student student2 = new Student();

        student1.name = "xiaoming";
        student1.age = 2;
        student2.name = "xiaohong";
        student2.age = 2;
        System.out.println(student1.name);
        System.out.println(student2.age);
    }
}

构造器详解

  • 一个类即使什么都不写,依然可以new实例化,因为会自动存在一个构造方法

  • 类的构造器也称为构造方法,是在进行创建对象的时候必须要调用,并且构造器有以下两个特点

    1. 必须和类的名字相同

    2. 必须没有返回类型,也不能写void

// 例如一个这样的类
class Student {}

// 编译后会变成如下样子,会自动添加一个方法
// 这被称为无参构造器,可以帮忙初始化一些东西
class Student {
    // 实例化初始值
    public Student(){
    }
}
package Demo;

// 学生类,一个类里面只能有属性和方法两种东西
public class Student {
    // 属性
    String name;
    int age;

    // 构造器.不写会自动生成,这里手写一下,同时初始化一下值
    public Student() {
        this.name = "你的名字";
    }

    // 方法
    // this指的是当前类
    public void study() {
        System.out.println(this.name + "在学习");
    }
}
package Demo;

// 一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        Student student1 = new Student();
        System.out.println(student1.name);
    }
}
  • 构造器的作用
    1. 使用new关键字,必须要有构造器,因为本质是在调用构造器
    2. 有参构造:一旦定义了有参构造,无参构造就必须显式定义
    3. alt+insert可以快捷地生成构造器
    4. 可以定义多个构造器,到时候需要哪个就会自动调用哪个
package Demo;

// 学生类,一个类里面只能有属性和方法两种东西
public class Student {
    // 属性
    String name;
    int age;

    // 构造器.不写会自动生成,这里手写一下,同时初始化一下值
    public Student() {
        this.name = "你的名字";
    }

    // 有参构造一旦定义了有参构造,无参构造就必须显式定义
    public Student(String name) {
        this.name = name;
    }

    // 方法
    // this指的是当前类
    public void study() {
        System.out.println(this.name + "在学习");
    }
}
package Demo;

// 一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        Student student1 = new Student("xueyan");
        System.out.println(student1.name);
    }
}

创建对象的内存分析

java程序运行时主要分以下几步

  1. 先加载每一个类,同时读取类中的方法和常量,此时会同步加载static静态方法(因为static与类一起加载,所以之后类中可以直接调用)
  2. main方法放到栈底,因为栈是先进后出,当main方法出栈的时候可以基本理解为程序运行结束
  3. 实例化类,每个实例会作为引用变量放到栈中间(注意,这里只是一个引用)
  4. 每个实例的对象(具体的值,方法等)会存储在中,每个实例可以调用静态方法

image

简单小结类和对象

  • 类是一个模板(抽象),对象是一个具体的实例
  • 方法的定义和调用
  • 对象的引用
    • 引用类型:对象是通过引用来操作的(对象引用放在栈当中,具体操作的实际上是堆)
    • 基本类型(8种)
  • 属性=字段field=成员变量(对象当中只有引用和方法),属性会进行默认初始化
    • 修饰符 属性类型 属性名=属性值
  • 对象的创建和使用
    • 必须使用new关键字创建,必须具有构造器(构造器不写编译器会默认生成)
    • 对象的属性
    • 对象的方法
  • 类,只有以下两个东西
    • 静态的属性,即属性
    • 动态的行为,即方法

封装详解

  • 封装:简单理解就像人把东西放在箱子中,要拿东西只能通过固定的口去拿出来

  • 该露的露,该藏的藏

    • 程序设计追求高内聚,低耦合,高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合就是只暴露少量的方法给外部使用
    • 类似于电视:我们只用遥控器就可以操作,显像管什么的不需要了解
  • 封装(数据的隐藏)

    • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这被称为信息隐藏
  • 记住这句话:属性私有,get/set

  • 封装更多针对属性而言,方法用不到多少封装

  • 方法重载,方法名称一致,但输入值或者返回值类型不同,编译器会自动调用适合的方法

  • 封装的好处

    1. 提高程序的安全性,保护数据
    2. 隐藏代码的实现细节
    3. 统一接口
    4. 系统可维护性增加
package Demo;

// 学生类,一个类里面只能有属性和方法两种东西
public class Student {
    // 属性私有
    private String name;
    private int id;
    private char sex;
    private int age;

    // 提供一些可以操作这个私有属性的方法
    // 提供一些public的get/set方法
    // get获取数据,set给数据设置值
    // alt+insert可以自动生成get/set方法
    public String getName() {
        return this.name;
    }

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

    // 通过封装,可以在输入值的时候进行属性判断
    public void setAge(int age) {
        if (age < 0 || age > 120) {
            age = 3;
            this.age = age;
        } else {
            this.age = age;
        }
    }

    public int getAge() {
        return this.age;
    }
}
package Demo;

// 一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.setName("你的名字");  // 设置名字
        System.out.println(student.getName());  // 获取名字
        student.setAge(140);
        System.out.println(student.getAge());
    }
}

继承

  • 继承的本质是对一批类进行抽象(类太多了的情况也需要进行抽象),例如人的基因虽然每个人或多或少不同,但基因中都表现了人都有手有脚
  • 继承是类与类之间的一种关系.除此之外,类与类之间的关系还有依赖,组合,聚合等
  • 继承分子类(扩展类)和父类(基类),子类继承父类用extends表示
    • 父类:被继承的类,例如人
    • 子类(扩展类):例如学生是人,继承了人的所有共性,学生就是子类.子类可以继承父类的所有方法
  • extends的意思是扩展,子类是父类的扩展
  • java中只有单继承,没有多继承,即一个类只能继承单个类,例如基因上说,儿子只能有一个爸爸,一个爸爸却可以有多个儿子
  • object:在java中,所有类都直接或者间接继承Object
package Demo;

// 在java中,所有类都直接或者间接继承`Object`类
public class Person {

    private int money = 10_0000_0000;

    public void say() {
        System.out.println("人说了一句话");
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}
package Demo;

// 子类继承父类,就会拥有父类的属性和全部方法
// 注意,如果父类使用了private修饰符,则子类就无法继承,一般属性都是私有的,公共的都是方法
public class Student extends Person {}
package Demo;

// 一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.say();  // say方法在Student中没有定义,但仍然可以调用父类
        System.out.println(student.getMoney());
    }
}

Super

package Demo;

// 一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.test("名字");
    }
}
package Demo;

// 在java中,所有类都直接或者间接继承`Object`类
public class Person {
    public Person(String name) {
        System.out.println("Person无参执行了");
    }

    protected String name = "xueyan";
}
package Demo;

// 子类继承父类,就会拥有父类的属性和全部方法
// 注意,如果父类使用了private修饰符,则子类就无法继承,一般属性都是私有的,公共的都是方法
public class Student extends Person {
    private String name = "狂神";

    // 执行子类构造器时,会先执行父类的构造器
    public Student(){
        // 隐藏代码,调用了父类的构造器
        super("name");  // 显式调用时,必须在第一行
        System.out.println("Student无参执行了");
    }

    // super代表调用父类方法,但如果父类中方法为private,则不能用super调用
    public void test(String name) {
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
    }
}

super注意点:

  • super调用父类的构造方法,必须在构造方法第一个
  • super必须只能出现在子类的方法或者构造方法中
  • superthis不能同时调用构造方法

superthis区别

  • 代表对象不同
    • super代表父类对象应用
    • this本身调用的对象
  • 前提
    • this没有继承也可以使用
    • super只有在继承情况下才可以使用
  • 构造方法
    • this():本类的构造器
    • super():父类的构造器

方法的重写

  • 重写都是方法的重写,与属性无关

  • 重写只发生在父子类之间

  • 重写只跟非静态公开方法有关,与静态方法没关系

  • 使用静态方法时

    package Demo;
    
    // 重写都是方法的重写,与属性无关
    public class A {
        public static void test() {
            System.out.println("A=>test()");
        }
    }
    
    package Demo;
    
    public class B extends A {
        public static void test() {
            System.out.println("B=>test()");
        }
    }
    
    package Demo;
    
    // 一个项目应该只存在一个main方法
    public class Application {
        public static void main(String[] args) {
            B b = new B();
            b.test();
    
            // 父类的引用指向了子类,实际上调用了B继承的父类A
            // 在静态方法时,方法的调用只和等号左边定义的数据类型有关
            A a = new B();
            a.test();
        }
    }
    
  • 不使用静态方法时

    package Demo;
    
    // 重写都是方法的重写,与属性无关
    public class A {
        public void test() {
            System.out.println("A=>test()");
        }
    }
    
    package Demo;
    
    public class B extends A {
        // 重写
        @Override  // 注解:有功能的注释
        public void test() {
            System.out.println("B=>test()");
        }
    }
    
    package Demo;
    
    // 一个项目应该只存在一个main方法
    public class Application {
        public static void main(String[] args) {
            B b = new B();
            b.test();
    
            // 父类的引用指向了子类,实际上调用了B继承的父类A
            // 在静态方法时,方法的调用只和等号左边定义的数据类型有关
            // 非静态方法时,父子类相同名称函数发生的就是重写
            A a = new B();
            a.test();
        }
    }
    
  • 重写总结:类之间必须有继承关系,子类重写父类的方法

    1. 方法名必须相同

    2. 参数列表必须相同

    3. 修饰符:范围可以扩大但不能缩小(子类修饰符范围可以大于父类修饰符的范围)

      public>protected>default>private

    4. 抛出的异常:范围可以被缩小,但不能扩大(子类的异常范围必须小于父类的异常范围)

    5. 子类的方法必须要和傅雷一直,但方法体不同

  • 为什么需要重写

    • 父类的功能,子类不一定需要,或者不一定满足.快捷键alt+insert

多态

  • 多态:统一方法可以根据发送对象的不同而采取多种行为方式
  • 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多(即一个对象实际类型肯定已知,但其引用对象的类型未知)
  • 用途:动态编译,一个数据的类型只有在运行时才完全确定,增强程序的可拓展性
  • 多态存在的条件
    • 类之间存在继承关系
    • 子类重写父类的方法
    • 父类引用指向子类对象
    • 注意:多态是方法的多态,属性没有多态
package Demo;

// 在java中,所有类都直接或者间接继承`Object`类
public class Person {

    public void run() {
        System.out.println("run");
    }
}
package Demo;

// 子类继承父类,就会拥有父类的属性和全部方法
// 注意,如果父类使用了private修饰符,则子类就无法继承,一般属性都是私有的,公共的都是方法
public class Student extends Person {
    @Override
    public void run() {
        System.out.println("son");
    }

    public void eat() {
        System.out.println("eat");
    }
}
package Demo;

// 一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        // 一个对象的实际类型是确定的,但可以指向的引用类型不确定
        // Student能调用的方法都是自己的或者继承父类的
        Student s1 = new Student();
        // 下面被称为父类的引用指向子类的类型,实际类型是student,引用的是person
        // 可以直观理解为,学生是人,同时亦是学生,一个人可以有多重身份
        Person p1 = new Student();
        // Person父类型,可以指向子类,但不能调用子类独有的方法
        Object o1 = new Student();

        // 父类的引用指向子类的类型,能执行什么方法其实取决于等号左边的引用类型
        s1.run();  // 当子类重写了父类的方法,执行的是子类的方法
        p1.run();
        s1.eat();
        p1.eat();  // 当引用的父类没有相关方法时,无法执行
    }
}
package Demo;

// 一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        // 一个对象的实际类型是确定的,但可以指向的引用类型不确定
        Student s1 = new Student();
        // 下面被称为父类的引用指向子类的类型,实际类型是student,引用的是person
        // 可以直观理解为,学生是人,同时亦是学生,一个人可以有多重身份
        Person p1 = new Student();
        Object o1 = new Student();

        // 父类的引用指向子类的类型,能执行什么方法其实取决于等号左边的引用类型
        s1.run();  // 当子类重写了父类的方法,执行的是子类的方法
        p1.run();
        ((Student) p1).eat();  // 将类型强制转换为Student后可以调用
    }
}
  • 多态注意事项

    • 多态是方法的多态,属性没有多态

    • 父类和子类,类之间必须有联系,错误的会报类型转换异常

    • 存在条件:类之间存在继承关系,方法需要被重写,同时父类引用指向子类对象

      Father f = new Son()

    • 有几种情况无法被重写

      • static方法,静态方法属于类,不属于实例
      • final定义的是常量
      • private私有方法

instanceof和类型转换

  • instanceof判断类型是否一致

  • 多态:父类引用指向子类的对象

  • 把子类转换为父类,叫做向上转型,不用强制转换

  • 把父类转换为子类,称作向下转换,需要强转换

  • 作用在于调用的时候把对象升级或者降级一下就可以调用,方便方法的调用,减少重复代码

package Demo;

// 在java中,所有类都直接或者间接继承`Object`类
public class Person {

    public void run() {
        System.out.println("run");
    }
}
package Demo;

public class Teacher extends Person {
}
package Demo;

// 子类继承父类,就会拥有父类的属性和全部方法
// 注意,如果父类使用了private修饰符,则子类就无法继承,一般属性都是私有的,公共的都是方法
public class Student extends Person {
    @Override
    public void run() {
        System.out.println("son");
    }

    public void eat() {
        System.out.println("eat");
    }
}
package Demo;

// 一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        // 一个对象的实际类型是确定的,但可以指向的引用类型不确定
        Object object = new Student();
        System.out.println(object instanceof Student);
        System.out.println(object instanceof Person);
        System.out.println(object instanceof Object);
        System.out.println(object instanceof Teacher);
        System.out.println(object instanceof String);
        System.out.println("========================");
        Person person = new Student();
        System.out.println(person instanceof Student);
        System.out.println(person instanceof Person);
        System.out.println(person instanceof Object);
        System.out.println(person instanceof Teacher);
        // System.out.println(object instanceof String); 编译报错,同级指标不能互相转换
        // 多态的操作实际上某种意义上进行了类型的轻质转换,从低类型转换为了高类型
        // 子类转换为父类可能会丢失一些方法
        Person p1 = new Student();
        ((Student)p1).eat();
    }
}

static关键字详解

  • 静态变量:用static修饰的变量,此类变量支持对象调用,且支持通过类名调用,也被称作类变量.当一个变量需要被很多类调用的时候可以使用
  • 静态方法与静态变量基本一致
package Demo;

// 一个项目应该只存在一个main方法
public class Application {
    private static int age;
    private double score;

    public static void main(String[] args) {
        Application application = new Application();
        System.out.println(Application.age);  // 通过类的方式调用
        System.out.println(application.age);  //通过对象调用
        go();  //静态对象与类一起加载,直接调用
    }

    public static void go() {
        System.out.println("go");
    }
}
  • java的类主体代码当中可以用{}来表示匿名代码块

    package Demo;
    
    // 静态导入包
    
    import static java.lang.Math;
    
    // 一个项目应该只存在一个main方法
    public class Application {
        // 匿名代码块意味着可以用来进行一些初始赋值,初始化
        {
            System.out.println("匿名代码块");
        }
    
        // 静态代码块只执行一次,只有第一次执行
        static {
            System.out.println("静态代码块");
        }
    
        public Application() {
            System.out.println("构造函数");
        }
    
        public static void main(String[] args) {
            Application application1 = new Application();
            System.out.println("============");
            Application application2 = new Application();
            System.out.println(Math.random());
        }
    }
    
  • 通过final修饰的类不能被继承

抽象类

  • abstract修饰符可以用来修饰方法也可以修饰类,修饰方法,该方法就是抽象方法;修饰类,就是休市内
  • 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类
  • 抽象类,不能使用new关键字来创建对象,主要是用来让子类继承的
  • 抽象方法,只有方法的声明而没有方法的实现,是用来让子类实现的
  • 子类继承抽象类,必须要实现抽象类没有实现的方法,否则该子类也要声明为抽象类
package Demo;

// abstract用于标识抽象类,该抽象类是寄希望于有人根据自己需要进行实现,抽象类主要起约束作用
public abstract class Person {
    // 抽象方法(只有方法名),具体功能别人实现,这里主要起到约束作用
    public abstract void doSomething();
}
package Demo;

// 抽象类的所有方法,继承了它的子类,都必须要实现相应方法,除非这个子类也是抽象类
// java类只允许继承一个类,即单继承
public class Teacher extends Person {
    @Override
    public void doSomething() {
        System.out.println("do it now");
    }
}

接口定义与实现

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有
  • 接口:只有规范,自己无法写方法,实现了约束和实现分离.工作中往往是面向接口编程,把接口定义好了,然后下面的人去实现就行
  • 接口就是规范.定义的是一组规则,就是说如果你是某一种东西,则必须能做到对应的事,体现了现实世界中“如果你是…则必须能…”的思想.例如:如果你是人,则必须能做到人能做到的事(思考等)
  • 接口的本质是契约,就跟法律一样,制定好后大家都遵守
  • 面向对象的精髓,是对对象的抽象.最能体现这一点的就是接口(因为都是抽象的规范,没有具体实现).为什么讨论设计模式都只针对具有抽象能力的语言,因为设计模式研究的,就是如何合理地去抽象.
  • 声明类的关键词class,声明接口的关键词interface
package Demo;

// 接口都需要有实现类
public interface UserService {
    // 接口的所有定义都默认是抽象的,public abstract这个可以默认不写
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}
package Demo;

public interface TimeService {
    void timer();
}
package Demo;

// 实现类的命名规范 类+实现类名称+implements+接口名称
// 实现了接口的类,就需要重写接口的方法,利用接口实现多继承(实际是实现)
public class UserInterfaceImpl implements UserService,TimeService{
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }

    @Override
    public void timer() {

    }
}
  • 总结
    • 接口主要提供规范和约束,不提供具体实现
    • 接口通过定义规范让不同的人去完成具体的规范,实现大规模协作
    • 接口中方法默认是public abstract
    • 接口中属性默认是public static final
    • 接口不能被实例化,接口没有构造方法
    • implements可以实现多个接口,变相实现了多继承
    • 接口的实现必须要重写接口中的方法

内部类

  • 内部类就是在一个类的内部定义一个类.比如,A类中定义一个B类,那么B类相对A类来说就被称为内部类,而A类相对B类来说就是外部类

  • 以下几种类型

    • 成员内部类

      package Demo;
      
      public class Outer {
          private int id = 10;
      
          public void out() {
              System.out.println("这是外部类的方法");
          }
      
          public class Inner {
              public void in() {
                  System.out.println("这是内部类的方法");
              }
      
              // 内部类可以获得外部类的私有属性
              public void getID() {
                  System.out.println(id);
              }
          }
      }
      
      package Demo;
      
      // 一个项目应该只存在一个main方法
      public class Application {
      
          public static void main(String[] args) {
              Outer outer = new Outer();
              outer.out();
              // 通过外部类实例化内部类
              Outer.Inner inner = outer.new Inner();
              inner.in();
              inner.getID();;
          }
      }
      
    • 静态内部类

      package Demo;
      
      public class Outer {
          private int id = 10;
      
          public void out() {
              System.out.println("这是外部类的方法");
          }
          
          // 静态内部类,此时无法获取非静态的属性
          public static class Inner {
              public void in() {
                  System.out.println("这是内部类的方法");
              }
          }
      }
      
    • 局部内部类

      package Demo;
      
      // 一个java文件中可以有多个class类,但只能有一个public class
      public class Outer {
          private int id = 10;
      
          public void method() {
              // 局部内部类
              class Inner {
                  public void in() {
                      
                  }
              }
          }
      }
      
    • 匿名内部类

      package Demo;
      
      // 一个java文件中可以有多个class类,但只能有一个public class
      public class Outer {
          private int id = 10;
      
          public void method() {
              // 局部内部类
              class Inner {
                  public void in() {
      
                  }
              }
          }
      }
      
      package Demo;
      
      // 一个项目应该只存在一个main方法
      public class Application {
      
          public static void main(String[] args) {
              // 没有名字初始化类,匿名内部类,不用将实例保存到对象中
              // 接口也一样
              new Outer().method();
          }
      }
      
 
出  处:https://www.cnblogs.com/hanxueyan/p/14811468.html


相关教程