Java(一): 对象和类

Java学习笔记,笔记内容来源:菜鸟编程、AI 提问的自我总结。

Java对象和类

Java作为一种面向对象语言。支持以下基本概念:

1、多态(Polymorphism)
定义

多态是指同一个操作(方法)作用于不同的对象时,可以有不同的表现形式。换句话说,不同的对象可以通过相同的方法调用,产生不同的行为。

示例:

在面向对象的编程中,子类可以重写(覆盖)父类的方法。当你调用这个方法时,实际执行的是子类中的版本,而不是父类中的版本。这种现象称为方法的多态性。

// 定义了一个 class 类 Animal
class Animal {
  // void :这个关键字的意思是 makeSound 方法没有返回值
  // 定义一个没有返回值的方法 makeSound
  void makeSound() {
    // System.out.println() 控制台打印消息,类似于 js 中的 console.log()
    System.out.println("Animal makes a sound");
  }
}

// 定义了一个 Dog 类,它继承于 Animal 父类
class Dog extends Animal {
  /*
   * @Override
   *   是 Java 中的一个注解,用于只是一个方法活构造函数重写了父类方法或构造函数
   *   这个注解在 Java5 中引入,用于提条代码的可读性和可维护性
   *
   *   用途:
   *     1、提高代码的可读性:通过在重写方法上使用 @Override 注解,可以清除地表明 这个方法是一个重写方法,
   *       而不是新定义地方法。这有助于其他开发者理解代码的意图
   *     2、编译时检查:使用 @OverRide 注解可以确保在编译时检查方法签名是否正确。
   *       如果方法签名与父类中的方法不匹配,编译器会报错,从而避免运行时错误
   * */
  @Override
  void makeSound() {
    System.out.println("Dog barks");
  }

}

// public 为主类,一个文件中只能有一个主类
public class case04 {
  // 定义一个方法,参数为字符串数组
  public static void main(String[] args) {
    // 创建一个Animal对象,类型为Dog
    Animal myAnimal = new Dog();
    // 调用Animal对象的makeSound方法
    myAnimal.makeSound();
  }
}
2、继承(Inheritance)
定义

继承是指一个类(子类)可以继承另一个类(父类)的属性和方法。继承实现了类之间的“是一个”(is-a)关系,并允许代码复用和扩展。

示例

Dog 类继承自 Animal 类,Dog 类获得了 Animal 类的属性和方法

class AnimalCase05 {
  void eat() {
    System.out.println("Animal eats");
  }
}

class DogCase05 extends AnimalCase05 {
  void bark() {
    System.out.println("Dog Barks");
  }
}

public class case05 {
  public static void main(String[] args) {
    DogCase05 myDog = new DogCase05();
    myDog.bark(); // 输出 "Dog Barks"
    myDog.eat(); // 输出 "Animal eats"
  }
}
3、封装(Encapsulation)
定义

封装是指将对象的状态(属性)和行为(方法)绑定在一起,并限制外部访问对象的内部实现细节。通过封装,内部数据可以被保护不被随意修改。

示例

通过将类的属性设置为 private,然后提供 public 的 getter 和 setter 方法来访问这些属性,实现封装

class PersonCase06 {
  // private 关键字表示这个成员的变量时私有的,只能在 类 的内部去访问
  private String name; // 私有成员变量
  
  // public 关键字表示这个方法时公共的,额可以从类的外部访问
  public String getName() {
    return name;
  }
  
  public void setName(String name) {
    this.name = name;
  }
}

public class case06 {
  public static void  main(String[] args) {
    PersonCase06 person = new PersonCase06();
    person.setName("张三");
    System.out.println(person.getName());
  }
}
4、抽象(Abstraction)
定义

抽象是指通过定义类或接口,隐藏复杂的实现细节,只暴露必要的功能和接口。抽象帮助程序员集中于高层次的操作,而不必关注具体的实现细节。

示例

可以使用抽象类和接口来定义抽象的方法,这些方法在子类中必须实现

abstract class AnimalCase07 {
  abstract void makeSound(); // 抽象方法
}

class DogCase07 extends AnimalCase07 {
  @Override // 方法重写
  void makeSound() {
    System.out.println("Dog barks");
  }
}

public class case07 {
  public static void main(String[] args) {
    // new DogCase07() 创建一个 DogCase07 实例
    // 将这个实例 赋值给 AnimalCase07 类型的引用变量 myDog
    AnimalCase07 myDog = new DogCase07();
    myDog.makeSound(); // 输出: Dog barks
  }
}
5、类(class)
定义

类是面向对象编程中的基本构造单元,它定义了对象的属性和行为。类是对象的蓝图或模板

示例

定义一个 Car 类,包含 colorspeed 属性,以及一个 drive 方法。

class Car {
  String color;
  int speed;

  void drive() {
    System.out.println("car is drive" + color + speed);
  }
}

class Main {
  public static void main(String[] args) {
    Car myCar = new Car();
    myCar.color = "red";
    myCar.speed = 100;
    myCar.drive(); // car is drive
  }
}
6、对象(Object)
定义

对象是类的实例。对象具有状态(属性)和行为(方法),并根据类的定义创建。

示例

使用 Car 类创建一个名为 myCar 的对象,并对其属性进行赋值和方法调用

class CarCase09 {
  String name;
  int age;
  String info;

  void getUserInfo() {
    System.out.println("用户名:" + name);
    System.out.println("用户年龄:" + age);
    System.out.println("用户介绍:" + info);
  }
}

public class case09{
  public static void main(String[] args) {
    CarCase09 myCar = new CarCase09();
    myCar.name = "张三";
    myCar.age = 10;
    myCar.info = "你好呀,我叫张三,今年10岁了,来自xx市...";
    myCar.getUserInfo();
  }
}
7、实例(Instance)
定义

实例是对象的另一个称呼。每次创建一个类的对象时,都会生成一个新的实例。

示例

myCarCar 类的一个实例,每个 Car 类的对象都是该类的一个实例。

Car myCar = new Car(); // myCar 是 Car 类的一个实例
8、方法(Method)
定义

方法是定义在类中的函数,用于描述对象的行为。方法可以操作对象的属性,并完成特定的任务。

示例

Car 类中的 drive 方法描述了 Car 对象的行为。

class Car {
    void drive() {
        System.out.println("Car is driving");
    }
}
9、方法重载(Method Overloading)
定义

重载是指在同一个类中定义多个同名但参数列表不同的方法。方法重载可以通过不同的参数类型、数量或顺序来实现

示例

Math 类中,add 方法可以重载以支持不同类型的参数。

class MathOperations {
    int add(int a, int b) {
        return a + b;
    }

    double add(double a, double b) {
        return a + b;
    }

    int add(int a, int b, int c) {
        return a + b + c;
    }
}

class Main {
    public static void main(String[] args) {
        MathOperations math = new MathOperations();
        System.out.println(math.add(2, 3)); // 输出: 5
        System.out.println(math.add(2.5, 3.5)); // 输出: 6.0
        System.out.println(math.add(1, 2, 3)); // 输出: 6
    }
}
对象和类的概念
  • 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
  • :类是一个模板,它描述一类对象的行为和状态。
Java 中的对象

现在让我们深入了解什么是对象。看看周围真实的世界,会发现身边有很多对象,车,狗,人等等。所有这些对象都有自己的状态和行为。

拿一条狗来举例,它的状态有:名字、品种、颜色,行为有:叫、摇尾巴和跑。

对比现实对象和软件对象,它们之间十分相似。

软件对象也有状态和行为。软件对象的状态就是属性,行为通过方法体现。

在软件开发中,方法操作对象内部状态的改变,对象的相互调用也是通过方法来完成。

Java 中的类

类可以看成是创建 Java 对象的模板。

示例
public class MyClass {
    // 类变量
    static String classVariable = "I'm a class variable";

    // 成员变量
    String instanceVariable = "I'm an instance variable";

    public void myMethod() {
        // 局部变量
        String localVariable = "I'm a local variable";

        // 访问局部变量
        System.out.println(localVariable);

        // 访问成员变量
        System.out.println(instanceVariable);

        // 访问类变量
        System.out.println(MyClass.classVariable);
    }

    public static void main(String[] args) {
        // 创建类的实例
        MyClass myObject = new MyClass();

        // 访问成员变量
        System.out.println(myObject.instanceVariable);

        // 访问类变量
        System.out.println(MyClass.classVariable);

        // 调用方法
        myObject.myMethod();
    }
}

一个类可以包含以下类型变量:

  • 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
  • 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
  • 类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。
构造方法

每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。

在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。

下面是一个构造方法示例:

public class Puppy{
    public Puppy(){
    }
 
    public Puppy(String name){
        // 这个构造器仅有一个参数:name
    }
}
创建对象

对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:

  • 声明:声明一个对象,包括对象名称和对象类型。
  • 实例化:使用关键字 new 来创建一个对象。
  • 初始化:使用 new 创建对象时,会调用构造方法初始化对象。

下面是一个创建对象的例子:

public class Puppy{
   public Puppy(String name){
      //这个构造器仅有一个参数:name
      System.out.println("小狗的名字是 : " + name ); 
   }
   public static void main(String[] args){
      // 下面的语句将创建一个Puppy对象
      Puppy myPuppy = new Puppy( "tommy" );
   }
}
访问实例变量和方法

通过已创建的对象来访问成员变量和成员方法,如下所示:

/* 实例化对象 */
Object referenceVariable = new Constructor();
/* 访问类中的变量 */
referenceVariable.variableName;
/* 访问类中的方法 */
referenceVariable.methodName();

使用 Object 类型声明变量只能在编译时访问 Object 类中的方法和属性,但在运行时,你可以通过强制类型转换将其转换为特定类型,以便访问特定类型的方法和属性。

实例
public class Puppy {
    private int age;
    private String name;
 
    // 构造器
    public Puppy(String name) {
        this.name = name;
        System.out.println("小狗的名字是 : " + name);
    }
 
    // 设置 age 的值
    public void setAge(int age) {
        this.age = age;
    }
 
    // 获取 age 的值
    public int getAge() {
        return age;
    }
 
    // 获取 name 的值
    public String getName() {
        return name;
    }
 
    // 主方法
    public static void main(String[] args) {
        // 创建对象
        Puppy myPuppy = new Puppy("Tommy");
 
        // 通过方法来设定 age
        myPuppy.setAge(2);
 
        // 调用另一个方法获取 age
        int age = myPuppy.getAge();
        System.out.println("小狗的年龄为 : " + age);
 
        // 也可以直接访问成员变量(通过 getter 方法)
        System.out.println("变量值 : " + myPuppy.getAge());
    }
}

编译并运行上面的程序,产生如下结果:

小狗的名字是 : tommy
小狗的年龄为 : 2
变量值 : 2
源文件声明规则

当在一个源文件中定义多个类,并且还有import语句和package语句时,要特别注意这些规则。

  • 一个源文件中只能有一个 public 类
  • 一个源文件可以有多个非 public 类
  • 源文件的名称应该和 public 类的类名保持一致。例如:源文件中 public 类的类名是 Employee,那么源文件应该命名为Employee.java。
  • 如果一个类定义在某个包中,那么 package 语句应该在源文件的首行。
  • 如果源文件包含 import 语句,那么应该放在 package 语句和类定义之间。如果没有 package 语句,那么 import 语句应该在源文件中最前面。
  • import 语句和 package 语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。

类有若干种访问级别,并且类也分不同的类型:抽象类和 final 类等。

除了上面提到的几种类型,Java 还有一些特殊的类,如:内部类匿名类

Java 包

包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。

在 Java 中,包(Package) 是一种组织类和接口的机制,主要用于将相关的类和接口分组在一起,提供了一种命名空间以避免命名冲突。包的使用使得代码更具可管理性和可重用性。

1、包的作用
  • 命名空间管理:包可以防止类名冲突。例如,如果两个不同的开发人员创建了同名的类,可以将它们放在不同的包中。
  • 访问控制:包提供了访问控制,允许类之间定义不同的可见性(public、protected、private)。
  • 组织代码:将相关的类放在同一个包中,可以提高代码的可读性和可维护性。
2、创建包

在 Java 中,你可以使用 package 关键字创建一个包。通常,包名是由小写字母组成的,常常使用反向域名的形式(如 com.example.project)。以下是一个创建包的示例:

// 文件名:MyClass.java
package com.example.myapp; // 定义包名 com.example.myapp 的意思时 Myclass 类在 com/example/myapp 目录下

public class MyClass {
    public void display() {
        System.out.println("Hello from MyClass!");
    }
}
3、使用包中的类

要使用另一个包中的类,你需要在你的 Java 文件的顶部使用 import 语句导入该类。然后,你就可以创建该类的实例或调用其方法了。以下是如何使用包中的类的示例:

假设你已经定义了一个包 com.example.myapp,并且在其中有一个类 MyClass

// 文件名:MyClass.java
package com.example.myapp;

public class MyClass {
    public void display() {
        System.out.println("Hello from MyClass!");
    }
}

现在你想在另一个类中使用 MyClass。你需要导入它并使用它:

// 文件名:Main.java
import com.example.myapp.MyClass; // 导入包中的类

public class Main {
    public static void main(String[] args) {
        MyClass myClass = new MyClass(); // 创建 MyClass 的实例
        myClass.display(); // 调用方法
    }
}
4. 编译和运行

编译和运行包中的类时,需要注意以下几点:

  1. 目录结构:包名与文件的目录结构要一致。例如,如果包名是 com.example.myapp,则 MyClass.java 文件应该在 com/example/myapp 目录中。

  2. 编译:使用 javac 编译器编译代码时,你需要从源代码的根目录开始。例如,假设你的源代码位于 src 目录下,命令如下:

    javac src/com/example/myapp/MyClass.java
    javac src/Main.java
    
  3. 运行:运行程序时,你需要指定完全限定的类名(包括包名)。继续使用上面的示例,运行 Main 类的命令如下:

    java -cp src Main
    
5、常用的包和库

Java 标准库中有许多常用的包,例如:

  • java.lang:包含 Java 语言的核心类,如 StringMathSystem 等。这个包默认导入,所以你不需要显式地导入。
  • java.util:包含实用工具类,如集合框架(ListMap)、日期和时间类等。
  • java.io:包含用于输入和输出操作的类,如 FileInputStreamOutputStream 等。
  • java.net:用于网络编程的类,如 SocketURLHttpURLConnection 等。

使用这些包时,你只需在代码中导入相关的类,例如:

import java.util.ArrayList;
import java.util.HashMap;
6、总结
  1. 定义包:使用 package 关键字。
  2. 导入包:使用 import 语句。
  3. 编译和运行:确保正确的目录结构,使用 javac 编译,使用 java 运行。
  4. 常用包:了解 Java 标准库中的常用包,利用它们简化开发工作。
import 语句

在 Java 中,如果给出一个完整的限定名,包括包名、类名,那么 Java 编译器就可以很容易地定位到源代码或者类。import 语句就是用来提供一个合理的路径,使得编译器可以找到某个类。

例如,下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类

import java.io.*;
匿名类(Anonymous Classes)
  1. 定义与特点
    • 匿名类没有类名,直接在创建对象的地方定义。
    • 它可以实现一个接口或继承一个类,并同时定义类的内容。
    • 由于匿名类没有名称,因此它不能被重复使用,通常只用于一次性任务。
  2. 创建方式
    • 匿名类是在创建对象时同时定义类的实现,语法形式通常是在new关键字后面直接跟上接口名称或父类名称,然后是大括号{}内的类实现。
  3. 使用场景
    • 当需要创建一个只需要使用一次的类时,可以使用匿名类,这样可以避免为这种一次性使用的类单独定义一个类文件。
    • 在处理事件监听、回调函数或临时需要实现的接口时,匿名类非常有用。
  4. 示例
    • 例如,在Java Swing中,我们经常使用匿名类来为按钮添加点击事件监听器,如button.addActionListener(new ActionListener() {...});
  5. 限制
    • 由于匿名类没有类名,因此不能在其他地方引用或实例化。
    • 匿名类通常不能访问外部类的非静态成员变量和方法(除非是final的),但可以访问外部类的静态成员和方法。

综上所述,匿名类是Java中一种便捷的类定义方式,特别适用于需要快速创建一次性使用的对象的情况。

案例:
/*
* 这些导入的包和类在Java Swing中用于创建图形用户界面(GUI)。下面是每个导入包和类的作用:
* 1. `javax.swing.JButton`:这个类用于创建按钮组件。按钮可以包含文本或图标,并且可以响应点击事件。
* 2. `javax.swing.JFrame`:这个类用于创建框架窗口。框架窗口是GUI应用程序的主窗口,可以包含标题栏、菜单栏、工具栏等。
* 3. `javax.swing.JOptionPane`:这个类用于显示对话框。对话框可以用于显示消息、获取用户输入、显示错误信息等。
* 4. `javax.swing.JPanel`:这个类用于创建面板组件。面板可以用于组织其他组件,例如按钮、文本框等。
* 5. `java.awt.event.ActionEvent`:这个类用于表示动作事件。动作事件通常由按钮点击、菜单项选择等操作触发。
* 6. `java.awt.event.ActionListener`:这个接口用于处理动作事件。实现这个接口的类可以注册为按钮或其他组件的动作监听器,以便在事件发生时执行特定的操作。
* 这些类和接口是Java Swing库的一部分,用于创建和管理图形用户界面。Java Swing提供了一套丰富的组件和布局管理器,可以用于创建各种类型的GUI应用程序。
* */

import javax.swing.JButton; // 导入JButton类
import javax.swing.JFrame; // 导入JFrame类
import javax.swing.JOptionPane; // 导入JOptionPane类
import javax.swing.JPanel; // 导入JPanel类
import java.awt.event.ActionEvent; // 导入ActionEvent类
import java.awt.event.ActionListener; // 导入ActionListener类

public class case14 {

  public static void main(String[] args) {
    // 创建一个 JFrame 实例,作为应用程序的主窗口
    JFrame frame = new JFrame("匿名类示例");
    frame.setSize(300, 200); // 设置窗口大小
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭操作

    // 创建一个 JPanel,用于容纳按钮
    JPanel panel = new JPanel();

    // 创建一个 JButton 实例
    JButton button = new JButton("点击我");

    // 使用匿名类创建 ActionListener 实例并添加到按钮
    button.addActionListener(new ActionListener() {
      // 匿名类实现了 ActionListener 接口
      @Override
      public void actionPerformed(ActionEvent e) {
        // 当按钮被点击时,显示一个消息框
        JOptionPane.showMessageDialog(frame, "按钮被点击了!");
      }
    });

    // 将按钮添加到面板
    panel.add(button);

    // 将面板添加到窗口
    frame.add(panel);

    // 设置窗口可见
    frame.setVisible(true);
  }
}

Java 中可以实现一个类中包含另外一个类,且不需要提供任何的类名直接实例化。

主要是用于在我们需要的时候创建一个对象来执行特定的任务,可以使代码更加简洁。

匿名类是不能有名字的类,它们不能被引用,只能在创建时用 new 语句来声明它们。

匿名类语法格式:

class outerClass {
    // 定义一个匿名类
    object1 = new Type(parameterList) {
         // 匿名类代码
    };
}

以上的代码创建了一个匿名类对象 object1,匿名类是表达式形式定义的,所以末尾以分号 ; 来结束。

匿名类通常继承一个父类或实现一个接口。

img

匿名类继承一个父类

以下实例中,创建了 Polygon 类,该类只有一个方法 display(),AnonymousDemo 类继承了 Polygon 类并重写了 Polygon 类的 display() 方法:

实例
class Polygon {
   public void display() {
      System.out.println("在 Polygon 类内部");
   }
}

class AnonymousDemo {
   public void createClass() {

      // 创建的匿名类继承了 Polygon 类
      Polygon p1 = new Polygon() {
         public void display() {
            System.out.println("在匿名类内部。");
         }
      };
      p1.display();
   }
}

class Main {
   public static void main(String[] args) {
       AnonymousDemo an = new AnonymousDemo();
       an.createClass();
   }
}

执行以上代码,匿名类的对象 p1 会被创建,该对象会调用匿名类的 display() 方法,输出结果为:

在匿名类内部。
匿名类实现一个接口

以下实例创建的匿名类实现了 Polygon 接口:

实例
interface Polygon {
   public void display();
}

class AnonymousDemo {
   public void createClass() {

      // 匿名类实现一个接口
      Polygon p1 = new Polygon() {
         public void display() {
            System.out.println("在匿名类内部。");
         }
      };
      p1.display();
   }
}

class Main {
   public static void main(String[] args) {
      AnonymousDemo an = new AnonymousDemo();
      an.createClass();
   }
}

输出结果为:

在匿名类内部。
内部类(Inner Class)

内部类(Inner Class)是指在一个类的内部定义的类。内部类可以访问外部类的成员(包括私有成员),并可以用于组织代码,使其更加清晰和易于管理。Java 支持多种类型的内部类,包括:

  1. 成员内部类:定义在另一个类的内部,并可以访问其外部类的属性和方法。

    public class OuterClass {
        private String outerField = "外部类字段";
    
        // 定义成员内部类
        public class InnerClass {
            public void display() {
                System.out.println("访问内部类中的外部类字段: " + outerField);
            }
        }
        
        public void createInnerClass() {
            InnerClass inner = new InnerClass();
            inner.display();
        }
    
        public static void main(String[] args) {
            OuterClass outer = new OuterClass();
            outer.createInnerClass();
        }
    }
    
  2. 静态内部类:与成员内部类类似,但用 static 修饰,可以不依赖于外部类的实例。

    public class OuterClass {
        private static String staticOuterField = "静态外部类字段";
    
        // 定义静态内部类
        public static class StaticInnerClass {
            public void display() {
                System.out.println("访问静态内部类中的外部类静态字段: " + staticOuterField);
            }
        }
    
        public static void main(String[] args) {
            StaticInnerClass staticInner = new StaticInnerClass();
            staticInner.display();
        }
    }
    
  3. 局部内部类:定义在方法内部,作用域仅限于该方法。

    public class OuterClass {
        public void methodWithLocalInnerClass() {
            // 定义局部内部类
            class LocalInnerClass {
                public void display() {
                    System.out.println("这是局部内部类方法!");
                }
            }
            LocalInnerClass localInner = new LocalInnerClass();
            localInner.display();
        }
    
        public static void main(String[] args) {
            OuterClass outer = new OuterClass();
            outer.methodWithLocalInnerClass();
        }
    }
    
  4. 匿名内部类:没有名称的内部类,通常用于实现接口或扩展类的实例。

    public class OuterClass {
        public void createAnonymousClass() {
            // 使用匿名内部类实现接口
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println("这是匿名内部类的实现!");
                }
            };
            
            // 创建一个新线程,并启动
            new Thread(runnable).start();
        }
    
        public static void main(String[] args) {
            OuterClass outer = new OuterClass();
            outer.createAnonymousClass();
        }
    }
    

Java 一个类中可以嵌套另外一个类,语法格式如下:

class OuterClass {   // 外部类
    // ...
    class NestedClass { // 嵌套类,或称为内部类
        // ...
    }
}

要访问内部类,可以通过创建外部类的对象,然后创建内部类的对象来实现。

嵌套类有两种类型:

  • 非静态内部类
  • 静态内部类
非静态内部类

非静态内部类是一个类中嵌套着另外一个类。 它有访问外部类成员的权限, 通常被称为内部类。

由于内部类嵌套在外部类中,因此必须首先实例化外部类,然后创建内部类的对象来实现。

实例
class OuterClass {
  int x = 10;
  class InnerClass {
    int y = 5;
  }
}

public class MyMainClass {
  public static void main(String[] args) {
    OuterClass myOuter = new OuterClass();
    OuterClass.InnerClass myInner = myOuter.new InnerClass();
    System.out.println(myInner.y + myOuter.x);
  }
}

以上实例执行输出结果为:

15
私有的内部类

内部类可以使用 private 或 protected 来修饰,如果你不希望内部类被外部类访问可以使用 private 修饰符:

实例
class OuterClass {
  int x = 10;

  private class InnerClass {
    int y = 5;
  }
}

public class MyMainClass {
  public static void main(String[] args) {
    OuterClass myOuter = new OuterClass();
    OuterClass.InnerClass myInner = myOuter.new InnerClass();
    System.out.println(myInner.y + myOuter.x);
  }
}

以上实例 InnerClass 设置为私有内部类,执行会报错:

MyMainClass.java:12: error: OuterClass.InnerClass has private access in OuterClass
    OuterClass.InnerClass myInner = myOuter.new InnerClass();
             ^
静态内部类

静态内部类可以使用 static 关键字定义,静态内部类我们不需要创建外部类来访问,可以直接访问它:

class OuterClass {
  int x = 10;

  static class InnerClass {
    int y = 5;
  }
}

public class MyMainClass {
  public static void main(String[] args) {
    OuterClass.InnerClass myInner = new OuterClass.InnerClass();
    System.out.println(myInner.y);
  }
}

以上实例执行输出结果为:

5

**注意:**静态内部类无法访问外部类的成员

从内部类访问外部类成员

内部类一个高级的用法就是可以访问外部类的属性和方法:

class OuterClass {
  int x = 10;

  class InnerClass {
    public int myInnerMethod() {
      return x;
    }
  }
}

public class MyMainClass {
  public static void main(String[] args) {
    OuterClass myOuter = new OuterClass();
    OuterClass.InnerClass myInner = myOuter.new InnerClass();
    System.out.println(myInner.myInnerMethod());
  }
}

以上实例执行输出结果为:

10
erClass has private access in OuterClass
    OuterClass.InnerClass myInner = myOuter.new InnerClass();
             ^
静态内部类

静态内部类可以使用 static 关键字定义,静态内部类我们不需要创建外部类来访问,可以直接访问它:

class OuterClass {
  int x = 10;

  static class InnerClass {
    int y = 5;
  }
}

public class MyMainClass {
  public static void main(String[] args) {
    OuterClass.InnerClass myInner = new OuterClass.InnerClass();
    System.out.println(myInner.y);
  }
}

以上实例执行输出结果为:

5

**注意:**静态内部类无法访问外部类的成员

从内部类访问外部类成员

内部类一个高级的用法就是可以访问外部类的属性和方法:

class OuterClass {
  int x = 10;

  class InnerClass {
    public int myInnerMethod() {
      return x;
    }
  }
}

public class MyMainClass {
  public static void main(String[] args) {
    OuterClass myOuter = new OuterClass();
    OuterClass.InnerClass myInner = myOuter.new InnerClass();
    System.out.println(myInner.myInnerMethod());
  }
}

以上实例执行输出结果为:

10
总结

这篇文章的内容就到这里了,如果你感觉这篇文章对你有帮助的话请点赞、收藏 ➕ 关注。

感谢您的阅读,这里是***开发小白***,期待与您的下次相遇(●’◡’●) ~

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值