• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

奋斗的软件工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

Java 中类的组成成分有哪些?

Java 中类的组成成分有哪些?

在 Java 中,类是构成程序的基本单元。类由以下几个部分组成:

类名:用于标识类的名称。

修饰符:用于控制类的访问权限。

成员变量:用于存储类的数据。

成员方法:用于定义类的行为。

构造方法(构造器):用于创建类的实例。

内部类:【成员、静态、局部、匿名】可以将一个类的定义放在另外一个类的定义内部。

代码块:【静态、局部、构造、同步】用于在类中定义一段代码,该代码块可以被多个成员方法访问。

1. 类名

类名是类的标识符,必须遵循以下规则:

  • 必须以字母、下划线或美元符号开头。

  • 只能包含字母、数字、下划线和美元符号。

  • 不能使用 Java 关键字。

2. 修饰符

修饰符用于控制类的访问权限。Java 中的修饰符包括:

  • public:公共的,可以在任何地方访问。

  • protected:受保护的,只能在类本身及其子类中访问。

  • package-private:缺省,只有在同一个包中的类才能访问。

  • private:私有的,只能在类内部访问。

3. 成员变量

成员变量用于存储类的数据。成员变量可以是任何 Java 数据类型,包括基本数据类型和引用数据类型。

4. 成员方法

成员方法用于定义类的行为。成员方法可以是任何 Java 数据类型,包括基本数据类型和引用数据类型。

5. 构造方法

构造方法用于创建类的实例。构造方法的名称必须与类名相同,并且不能指定返回值类型。

6.内部类

可以将一个类的定义放在另外一个类的定义内部,可以提高代码的 结构性 和 可维护性。

成员内部类

成员内部类是最常见的内部类,它和外部类的成员变量一样,定义在类的内部,可以声明访问修饰符。

特点:

  • 可以访问外部类的所有成员(包括私有成员和静态成员)。
  • 不可以定义静态成员和方法,因为内部类是外部类的一个成员,只有当外部类初始化时,内部类才能初始化,静态变量属于类级别,在类加载的时候就初始化,所以两者本身在语法上就有矛盾。
  • 但可以定义常量。
public class OuterClass {

    private int num = 10;

    public class InnerClass {

        public void printNum() {
            System.out.println(num); // 可以访问外部类的私有成员
        }
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        innerClass.printNum();
    }
}

代码功能:

定义一个 Car 类,用于表示一辆汽车

定义一个 Engine 类,用于表示汽车发动机

创建一辆奥迪 A8L 汽车并设置其属性

创建一辆宝马 X5 汽车并设置其属性

代码特点:

使用了成员内部类来定义 Engine 类

Engine 类可以访问 Car 类的所有成员,包括私有成员

使用了链式调用来设置 Car 对象的属性

代码示例:

点击查看代码
public class App {

    /**
     * 当一个类的内部,包含了一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类。
     * 
     * 成员内部类 就是类中的一个普通成员,类似前面我们学过的普通的成员变量、成员方法。
     */
    public static void main(String[] args) {
        // 外部类名.内部类名 对象名 = new 外部类(...).new 内部类(...);


        // 创建奥迪汽车
        Car audiA8L = new Car()
                .brand("奥迪")
                .style("A8L")
                .price(888888);

        Car.Engine engine_A8L = audiA8L.new Engine("黑色", 3.0, 90, "95 辛烷值");
        audiA8L.setEngine(engine_A8L);

        System.out.println(audiA8L);

        // 创建宝马汽车
        Car bmwX5 = new Car()
                .brand("宝马")
                .style("X5")
                .price(999999);

        Car.Engine engine_X5 = bmwX5.new Engine("白色", 4.0, 95, "98 辛烷值");
        bmwX5.setEngine(engine_X5);

        System.out.println(bmwX5);


    }
}

/**
 * 定义一个 `Car` 类,用于表示一辆汽车
 */
class Car {

    /**
     * 汽车品牌
     */
    private String brand;

    /**
     * 汽车款式
     */
    private String style;

    /**
     * 汽车价格
     */
    private double price;

    private Engine engine;


    /**
     * 无参构造函数,创建一个没有任何属性值的汽车对象
     */
    public Car() {
    }

    /**
     * 带参构造函数,创建一个指定品牌、款式和价格的汽车对象
     *
     * @param brand  汽车品牌
     * @param style  汽车款式
     * @param price  汽车价格
     * @param engine 汽车引擎
     */
    public Car(String brand, String style, double price, Car.Engine engine) {
        this.brand = brand;
        this.style = style;
        this.price = price;
        this.engine = engine;
    }

    /**
     * 获取汽车品牌
     *
     * @return 汽车品牌
     */
    public String getBrand() {
        return this.brand;
    }

    /**
     * 设置汽车品牌
     *
     * @param brand 汽车品牌
     */
    public void setBrand(String brand) {
        this.brand = brand;
    }

    /**
     * 获取汽车款式
     *
     * @return 汽车款式
     */
    public String getStyle() {
        return this.style;
    }

    /**
     * 设置汽车款式
     *
     * @param style 汽车款式
     */
    public void setStyle(String style) {
        this.style = style;
    }

    /**
     * 获取汽车价格
     *
     * @return 汽车价格
     */
    public double getPrice() {
        return this.price;
    }

    /**
     * 设置汽车价格
     *
     * @param price 汽车价格
     */
    public void setPrice(double price) {
        this.price = price;
    }

    public Engine getEngine() {
        return this.engine;
    }

    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    /**
     * 设置汽车品牌并返回当前对象,用于链式调用
     *
     * @param brand 汽车品牌
     * @return 当前对象
     */
    public Car brand(String brand) {
        setBrand(brand);
        return this;
    }

    /**
     * 设置汽车款式并返回当前对象,用于链式调用
     *
     * @param style 汽车款式
     * @return 当前对象
     */
    public Car style(String style) {
        setStyle(style);
        return this;
    }

    /**
     * 设置汽车价格并返回当前对象,用于链式调用
     *
     * @param price 汽车价格
     * @return 当前对象
     */
    public Car price(double price) {
        setPrice(price);
        return this;
    }

    /**
     * 创建一个 `Engine` 对象,并将其设置到当前 `Car` 对象中。
     *
     * @param color        发动机颜色
     * @param displacement 发动机排量(单位:升)
     * @param stroke       发动机行程(单位:毫米)
     * @param gasolineType 使用的汽油类型
     * @return 当前 `Car` 对象
     */
    public Engine createEngine(String color, double displacement, int stroke, String gasolineType) {
        Engine engine = new Engine(color, displacement, stroke, gasolineType);
        this.engine = engine;
        return engine;
    }

    /**
     * 重写 `toString()` 方法,定义如何将 `Car` 对象转换为字符串
     *
     * @return 表示汽车信息的字符串
     */
    @Override
    public String toString() {
        return "{" +
                " 汽车品牌='" + getBrand() + "'" +
                ",汽车款式='" + getStyle() + "'" +
                ",汽车价格='" + getPrice() + "'" +
                ",汽车引擎=" + getEngine().toString() +  // 调用 getEngine().toString() 输出 Engine 的信息
                "}";
    }

    /**
     * 定义一个 `Engine` 类,用于表示汽车发动机
     */
    class Engine {

        /**
         * 发动机颜色
         */
        private String color;

        /**
         * 发动机排量(单位:升)
         */
        private double displacement;

        /**
         * 发动机行程(单位:毫米)
         */
        private int stroke;

        /**
         * 使用的汽油类型
         */
        private String gasolineType;

        /**
         * 创建一个发动机对象,指定其颜色、排量、行程和汽油类型
         *
         * @param color        发动机颜色
         * @param displacement 发动机排量(升)
         * @param stroke       发动机行程(毫米)
         * @param gasolineType 使用的汽油类型
         */
        public Engine(String color, double displacement, int stroke, String gasolineType) {
            this.color = color;
            this.displacement = displacement;
            this.stroke = stroke;
            this.gasolineType = gasolineType;
        }

        /**
         * 获取发动机颜色
         *
         * @return 发动机颜色
         */
        public String getColor() {
            return color;
        }

        /**
         * 设置发动机颜色
         *
         * @param color 发动机颜色
         */
        public void setColor(String color) {
            this.color = color;
        }

        /**
         * 获取发动机排量
         *
         * @return 发动机排量(升)
         */
        public double getDisplacement() {
            return displacement;
        }

        /**
         * 设置发动机排量
         *
         * @param displacement 发动机排量(升)
         */
        public void setDisplacement(double displacement) {
            this.displacement = displacement;
        }

        /**
         * 获取发动机行程
         *
         * @return 发动机行程(毫米)
         */
        public int getStroke() {
            return stroke;
        }

        /**
         * 设置发动机冲程
         *
         * @param stroke 发动机冲程(毫米)
         */
        public void setStroke(int stroke) {
            this.stroke = stroke;
        }

        /**
         * 获取使用的汽油类型
         *
         * @return 使用的汽油类型
         */
        public String getGasolineType() {
            return gasolineType;
        }

        /**
         * 设置使用的汽油类型
         *
         * @param gasolineType 使用的汽油类型
         */
        public void setGasolineType(String gasolineType) {
            this.gasolineType = gasolineType;
        }

        /**
         * 重写 `toString()` 方法,定义如何将 `Engine` 对象转换为字符串
         *
         * @return 表示发动机信息的字符串
         */
        @Override
        public String toString() {
            return "{" +
                    "颜色='" + color + '\'' +
                    ",排量=" + displacement + "L" +
                    ",冲程=" + stroke + "mm" +
                    ",汽油类型='" + gasolineType + '\'' +
                    '}';
        }
    }

}

静态内部类

静态内部类与成员内部类类似,但它属于外部类的静态成员,与外部类的实例无关。

特点:

  • 可以访问外部类的静态成员,但不能访问外部类的非静态成员(包括私有成员)。

  • 可以定义静态成员和方法。

public class OuterClass {

    private static int num = 10;

    public static class InnerClass {

        public static void printNum() {
            System.out.println(num); // 可以访问外部类的静态成员
        }
    }

    public static void main(String[] args) {
        OuterClass.InnerClass.printNum(); // 不需要创建外部类的实例
    }
}

局部内部类-鸡肋,食之无味···

局部内部类定义在方法或代码块中,只能在该方法或代码块内访问。
特点:

  • 可以访问该方法或代码块中的所有变量,包括局部变量。

  • 只能在定义它的方法或代码块内使用。

public class OuterClass {

    public void printNum() {
        int num = 10;

        class InnerClass {

            public void print() {
                System.out.println(num); // 可以访问局部变量
            }
        }

        InnerClass innerClass = new InnerClass();
        innerClass.print();
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        outerClass.printNum();
    }
}

匿名内部类-重点

匿名内部类是局部内部类的简写形式,没有类名,直接使用 new 操作符创建。

特点:

  • 可以访问该方法或代码块中的所有变量,包括局部变量。

  • 只需创建一次,不能使用类名引用。

public class App {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.eat();// 猫吃鱼~~~

        new Animal() {
            public void eat() {
                System.out.println("猫吃鱼~~~");
            }

        }.eat();
    }
}

abstract class Animal {
    public abstract void eat();

}

class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼~~~");
    }
}

7.代码块

静态代码块

定义: 使用 static {} 包裹起来的代码片段。

特点:

  • 仅执行一次,在类加载时执行,且优先于构造代码块执行。
  • 属于类,与对象无关,所有该类的对象共享该代码块中的内容。
  • 常用于初始化静态成员变量、注册驱动程序等。
public class StaticCodeBlock {

    static {
        System.out.println("静态代码块");
    }

    public StaticCodeBlock() {
        System.out.println("构造代码块");
    }

    public static void main(String[] args) {
        new StaticCodeBlock();
        new StaticCodeBlock();

    }
}

静态代码块
构造代码块
构造代码块

构造代码块

定义: 直接在类中定义且没有加 static 关键字的代码块。

特点:

  • 在创建对象时被调用,每次创建对象都会被调用,且优先于类构造函数执行。
  • 属于对象,与类无关,每个对象都有自己的代码块副本。
  • 常用于初始化成员变量、执行一些初始化操作等。
public class ConstructorCodeBlock {

    private int num;

    {
        num = 10;
        System.out.println("构造代码块");
    }

    public ConstructorCodeBlock() {
        System.out.println("构造函数");
    }

    public static void main(String[] args) {
        new ConstructorCodeBlock();
        new ConstructorCodeBlock();
    }
}
构造代码块
构造函数
构造代码块
构造函数

普通代码块

定义: 在方法或语句中出现的 {} 就称为普通代码块。

特点:

  • 作用域仅限于该 {} 内,离开 {} 后其内部的变量空间会被回收。
  • 常用于控制流程、局部变量声明等。
public class NormalCodeBlock {

    public static void main(String[] args) {
        int num = 1;
        {
            int a = 2;
            System.out.println("普通代码块:" + num + ", " + a);
        }
        // System.out.println(a); // 编译错误,a 无法访问
    }
}
普通代码块:1, 2

同步代码块

定义: 使用 synchronized 关键字包裹起来的代码块。

特点:

  • 同步代码块中的代码只能由一个线程执行,其它线程试图进入该代码块时会阻塞,直到该线程执行完毕。
  • 常用于解决多线程并发访问问题,保证数据的完整性和一致性。
```public class SynchronizedCodeBlock {

    private int num = 0;

    public void increase() {
        synchronized (this) {
            num++;
        }
    }

    public static void main(String[] args) {
        SynchronizedCodeBlock scb = new SynchronizedCodeBlock();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    scb.increase();
                }
            }).start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(scb.num); // 10000
    }
}
10000

posted on 2024-03-04 20:12  周政然  阅读(735)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3