ITPub博客

首页 > 应用开发 > IT综合 > 继承中成员变量访问:就近原则与this/super用法解析

继承中成员变量访问:就近原则与this/super用法解析

翻译 IT综合 作者:bhluo 时间:2026-02-10 15:25:49 0 删除 编辑

# 继承中成员变量访问:就近原则与this/super用法解析


## 继承体系中的成员变量访问规则


在Java继承体系中,成员变量的访问遵循特定的优先级规则,理解这些规则对于避免字段访问混淆至关重要。


```java

// 多层继承中的成员变量访问

public class InheritanceFieldAccess {

    

    // 祖父类

    static class GrandParent {

        // 不同访问权限的成员变量

        public String publicField = "GrandParent公开字段";

        protected String protectedField = "GrandParent受保护字段";

        String packageField = "GrandParent包私有字段";  // 默认访问权限

        private String privateField = "GrandParent私有字段";

        

        // 公共访问方法

        public String getPrivateField() {

            return privateField;

        }

    }

    

    // 父类

    static class Parent extends GrandParent {

        // 隐藏父类的字段

        public String publicField = "Parent公开字段";

        protected String protectedField = "Parent受保护字段";

        

        // 新增字段

        public String parentOnlyField = "Parent特有字段";

    }

    

    // 子类

    static class Child extends Parent {

        // 隐藏父类的字段

        public String publicField = "Child公开字段";

        

        // 访问各种字段的方法

        public void accessFields() {

            System.out.println("=== 直接访问字段 ===");

            

            // 1. 访问自己的字段

            System.out.println("this.publicField: " + this.publicField);

            

            // 2. 访问父类被隐藏的字段

            System.out.println("super.publicField: " + super.publicField);

            

            // 3. 访问祖父类的字段(通过父类)

            System.out.println("super.protectedField: " + super.protectedField);

            

            // 4. 访问父类特有字段

            System.out.println("this.parentOnlyField: " + this.parentOnlyField);

            

            // 5. 尝试访问祖父类的包私有字段(在同一个包中可以访问)

            System.out.println("继承的packageField: " + packageField);

            

            // 6. 无法直接访问私有字段,需要通过公共方法

            System.out.println("通过方法访问privateField: " + getPrivateField());

            

            System.out.println("\n=== 使用不同类型引用访问 ===");

            

            // 使用不同类型的引用

            Child childRef = this;

            Parent parentRef = this;  // 向上转型

            GrandParent grandParentRef = this;  // 向上转型

            

            System.out.println("childRef.publicField: " + childRef.publicField);

            System.out.println("parentRef.publicField: " + parentRef.publicField);

            System.out.println("grandParentRef.publicField: " + grandParentRef.publicField);

        }

        

        // 演示字段隐藏的实际情况

        public void demonstrateFieldHiding() {

            System.out.println("\n=== 字段隐藏现象 ===");

            

            // 每个类都有自己的publicField副本

            System.out.println("内存中存在三个publicField:");

            System.out.println("1. GrandParent.publicField = " + 

                             ((GrandParent)this).publicField);

            System.out.println("2. Parent.publicField = " + 

                             ((Parent)this).publicField);

            System.out.println("3. Child.publicField = " + this.publicField);

            

            System.out.println("\n它们实际上是不同的内存位置");

        }

    }

    

    // 测试类

    static class TestClass {

        public void runTests() {

            Child child = new Child();

            child.accessFields();

            child.demonstrateFieldHiding();

            

            System.out.println("\n=== 多态与字段访问 ===");

            // 重要:字段访问没有多态性!

            GrandParent ref = new Child();

            System.out.println("GrandParent ref = new Child();");

            System.out.println("ref.publicField: " + ref.publicField);  // 访问GrandParent的字段

            System.out.println("实际对象类型: " + ref.getClass().getSimpleName());

        }

    }

    

    public static void main(String[] args) {

        new TestClass().runTests();

    }

}

```


## 就近原则的详细工作机制


就近原则(也称遮蔽或隐藏)决定了在继承链中哪个字段被优先访问。


```java

// 就近原则的深入分析

public class ProximityPrinciple {

    

    // 简单的三层继承结构

    static class Level1 {

        int value = 10;

        String name = "Level1";

        

        // 静态字段也遵循类似规则

        static int staticValue = 100;

    }

    

    static class Level2 extends Level1 {

        int value = 20;  // 隐藏Level1的value

        String name = "Level2";

        

        // 静态字段隐藏

        static int staticValue = 200;

        

        // 新增字段

        double price = 99.9;

    }

    

    static class Level3 extends Level2 {

        int value = 30;  // 隐藏Level2的value

        String name = "Level3";

        

        static int staticValue = 300;

        

        // 演示就近访问

        public void demonstrateProximity() {

            System.out.println("=== 实例字段的访问 ===");

            

            // 直接访问 - 访问最近的(自己的)

            System.out.println("直接访问value: " + value);          // 30

            System.out.println("直接访问name: " + name);           // 3

            

            // 使用this - 同样访问最近的

            System.out.println("this.value: " + this.value);       // 30

            System.out.println("this.name: " + this.name);         // "Level3"

            

            // 访问父类的被隐藏字段

            System.out.println("super.value: " + super.value);     // 20

            System.out.println("super.name: " + super.name);       // "Level2"

            

            // 访问祖父类的字段(需要转型)

            System.out.println("((Level1)this).value: " + 

                             ((Level1)this).value);                // 10

            System.out.println("((Level1)this).name: " + 

                             ((Level1)this).name);                 // "Level1"

            

            System.out.println("\n=== 静态字段的访问 ===");

            // 静态字段的访问基于引用类型,而非实际对象类型

            System.out.println("Level3.staticValue: " + Level3.staticValue);       // 300

            System.out.println("Level2.staticValue: " + Level2.staticValue);       // 200

            System.out.println("Level1.staticValue: " + Level1.staticValue);       // 100

            

            // 通过实例访问(不推荐,容易混淆)

            Level3 obj = this;

            System.out.println("obj.staticValue: " + obj.staticValue);             // 300

            System.out.println("((Level2)obj).staticValue: " + 

                             ((Level2)obj).staticValue);                           // 200

            

            System.out.println("\n=== 方法中的字段访问 ===");

            // 方法中的局部变量优先于字段

            int value = 999;  // 局部变量隐藏所有同名字段

            System.out.println("局部变量value: " + value);        // 999

            

            // 访问被隐藏的字段

            System.out.println("this.value: " + this.value);      // 30

            System.out.println("Level3.this.value: " + 

                             Level3.this.value);                  // 30

        }

        

        // 复杂场景:嵌套类中的字段访问

        class InnerClass {

            int value = 777;  // 内部类的字段

            

            void accessOuterFields() {

                System.out.println("\n=== 内部类中的字段访问 ===");

                System.out.println("直接访问value: " + value);               // 777

                System.out.println("this.value: " + this.value);            // 777

                System.out.println("Level3.this.value: " + 

                                 Level3.this.value);                         // 30

                System.out.println("Level3.super.value: " + 

                                 Level3.super.value);                        // 20

            }

        }

    }

    

    // 测试复杂继承情况

    static class ComplexCase {

        String field = "ComplexCase";

        

        class Inner {

            String field = "Inner";

            

            void test() {

                String field = "局部变量";

                

                System.out.println("field: " + field);                    // "局部变量"

                System.out.println("this.field: " + this.field);          // "Inner"

                System.out.println("ComplexCase.this.field: " + 

                                 ComplexCase.this.field);                 // "ComplexCase"

            }

        }

    }

    

    // 演示就近原则的实际影响

    public static void main(String[] args) {

        System.out.println("=== 就近原则演示 ===");

        

        Level3 level3 = new Level3();

        level3.demonstrateProximity();

        

        // 测试内部类

        Level3.InnerClass inner = level3.new InnerClass();

        inner.accessOuterFields();

        

        // 测试复杂情况

        ComplexCase complex = new ComplexCase();

        ComplexCase.Inner inner2 = complex.new Inner();

        inner2.test();

        

        System.out.println("\n=== 重要结论 ===");

        System.out.println("1. 字段访问优先级:局部变量 > 当前类字段 > 父类字段");

        System.out.println("2. 使用this访问当前类字段,super访问直接父类字段");

        System.out.println("3. 静态字段基于引用类型访问,与多态无关");

        System.out.println("4. 内部类可以访问外部类的字段,使用OuterClass.this.field");

    }

}

```


## this关键字的全方位应用


this关键字在继承体系中扮演着多重角色,不仅仅是访问当前对象。


```java

// this关键字的深度解析

public class ThisKeywordUsage {

    

    // 基础类

    static class BaseComponent {

        protected String id;

        protected String type;

        

        public BaseComponent(String id) {

            this.id = id;  // 区分参数和字段

            this.type = "Base";

            System.out.println("BaseComponent构造器: id=" + id);

        }

        

        // this作为返回值

        public BaseComponent setId(String id) {

            this.id = id;

            return this;  // 支持链式调用

        }

        

        public BaseComponent setType(String type) {

            this.type = type;

            return this;

        }

        

        public void display() {

            System.out.println("Base - ID: " + id + ", Type: " + type);

        }

        

        // this在方法调用中传递当前对象

        public void process() {

            System.out.println("处理基类组件: " + this);

            helperMethod(this);

        }

        

        protected void helperMethod(BaseComponent component) {

            System.out.println("帮助方法处理: " + component.id);

        }

    }

    

    // 派生类

    static class AdvancedComponent extends BaseComponent {

        private String version;

        private static int instanceCount = 0;

        private final int instanceId;

        

        public AdvancedComponent(String id, String version) {

            super(id);  // 必须首先调用父类构造器

            this.version = version;

            this.type = "Advanced";  // 修改继承的字段

            this.instanceId = ++instanceCount;

            System.out.println("AdvancedComponent构造器: id=" + id + 

                             ", version=" + version);

        }

        

        // 重写父类方法,使用super和this

        @Override

        public void display() {

            System.out.println("=== AdvancedComponent信息 ===");

            super.display();  // 调用父类方法

            System.out.println("Version: " + this.version);

            System.out.println("Instance ID: " + this.instanceId);

            System.out.println("Total Instances: " + instanceCount);

        }

        

        // 方法重载中使用this

        public AdvancedComponent setVersion(String version) {

            this.version = version;

            return this;

        }

        

        // 链式调用,混合super和this

        @Override

        public AdvancedComponent setId(String id) {

            super.setId(id);  // 调用父类方法

            return this;      // 返回当前对象

        }

        

        // this在内部类中的使用

        class ComponentInfo {

            void showAllInfo() {

                System.out.println("\n=== 内部类访问外部类字段 ===");

                System.out.println("外部类id: " + AdvancedComponent.this.id);

                System.out.println("外部类version: " + AdvancedComponent.this.version);

                System.out.println("内部类this: " + this);

                System.out.println("外部类this: " + AdvancedComponent.this);

            }

        }

        

        // 静态方法中的限制

        public static void showInstanceCount() {

            System.out.println("实例数量: " + instanceCount);

            // System.out.println(this.id);  // 错误:静态方法不能使用this

            // System.out.println(version);  // 错误:不能访问非静态字段

        }

        

        // this在同步块中的使用

        public void synchronizedOperation() {

            synchronized(this) {  // 使用当前对象作为锁

                System.out.println("同步操作开始: " + this.id);

                try {

                    Thread.sleep(100);

                } catch (InterruptedException e) {

                    Thread.currentThread().interrupt();

                }

                System.out.println("同步操作结束: " + this.id);

            }

        }

        

        // 返回当前对象的字符串表示

        @Override

        public String toString() {

            return String.format("AdvancedComponent{id='%s', type='%s', version='%s'}", 

                               id, type, version);

        }

    }

    

    // 测试this的各种用法

    public static void main(String[] args) {

        System.out.println("=== this关键字用法演示 ===");

        

        // 创建对象并测试链式调用

        AdvancedComponent comp1 = new AdvancedComponent("C001", "1.0")

            .setId("C001-Updated")

            .setType("Enhanced")

            .setVersion("2.0");

        

        comp1.display();

        

        System.out.println("\n=== 测试内部类 ===");

        AdvancedComponent.ComponentInfo info = comp1.new ComponentInfo();

        info.showAllInfo();

        

        System.out.println("\n=== 测试静态方法 ===");

        AdvancedComponent.showInstanceCount();

        

        System.out.println("\n=== 测试同步块 ===");

        Thread t1 = new Thread(() -> comp1.synchronizedOperation());

        Thread t2 = new Thread(() -> comp1.synchronizedOperation());

        t1.start();

        t2.start();

        

        try {

            t1.join();

            t2.join();

        } catch (InterruptedException e) {

            Thread.currentThread().interrupt();

        }

        

        System.out.println("\n=== 测试toString ===");

        System.out.println("对象字符串表示: " + comp1);

        

        System.out.println("\n=== this的关键用途总结 ===");

        System.out.println("1. 区分字段和局部变量");

        System.out.println("2. 在构造器中调用其他构造器(this())");

        System.out.println("3. 支持方法链式调用(return this)");

        System.out.println("4. 在内部类中访问外部类实例");

        System.out.println("5. 作为方法参数传递当前对象");

        System.out.println("6. 在同步块中作为监视器对象");

        System.out.println("7. 实现toString()方法");

    }

}

```


## super关键字的精确使用


super关键字专门用于访问父类的成员,在特定场景下不可或缺。


```java

// super关键字的专业用法

public class SuperKeywordMastery {

    

    // 多层继承结构

    static class Vehicle {

        protected String brand;

        protected int speed;

        protected static String vehicleType = "通用交通工具";

        

        public Vehicle(String brand) {

            this.brand = brand;

            this.speed = 0;

            System.out.println("Vehicle构造器: " + brand);

        }

        

        public void start() {

            System.out.println(brand + " 启动");

        }

        

        public void accelerate(int increment) {

            speed += increment;

            System.out.println(brand + " 加速到 " + speed + " km/h");

        }

        <"abb.j9k5.org.cn"><"avg.j9k5.org.cn"><"avr.j9k5.org.cn">

        public static void showType() {

            System.out.println("车辆类型: " + vehicleType);

        }

        

        protected void maintenance() {

            System.out.println("执行基础维护");

        }

    }

    

    static class Car extends Vehicle {

        protected int doorCount;

        protected static String vehicleType = "汽车";

        

        public Car(String brand, int doorCount) {

            super(brand);  // 必须首先调用父类构造器

            this.doorCount = doorCount;

            System.out.println("Car构造器: " + brand + ", " + doorCount + "门");

        }

        

        @Override

        public void start() {

            super.start();  // 调用父类方法

            System.out.println("检查车门: " + doorCount + "个门已关好");

        }

        

        // 重写并扩展父类方法

        @Override

        public void accelerate(int increment) {

            if (increment > 100) {

                System.out.println("汽车限速100km/h");

                increment = 100;

            }

            super.accelerate(increment);  // 调用父类实现

            System.out.println("当前档位: D档");

        }

        

        // 访问父类的静态字段

        public void showParentStaticField() {

            System.out.println("父类静态字段: " + super.vehicleType);

            System.out.println("子类静态字段: " + this.vehicleType);

            System.out.println("通过类名访问: " + Vehicle.vehicleType);

        }

        

        // 无法重写静态方法,但可以隐藏

        public static void showType() {

            System.out.println("子类静态方法调用父类: ");

            Vehicle.showType();  // 使用类名,不是super

            System.out.println("当前类类型: " + vehicleType);

        }

        

        @Override

        protected void maintenance() {

            System.out.println("=== 汽车专业维护 ===");

            super.maintenance();  // 调用父类基础维护

            System.out.println("1. 更换机油");

            System.out.println("2. 检查刹车系统");

            System.out.println("3. 轮胎对调");

        }

        

        // 子类特有方法

        public void openSunroof() {

            System.out.println("打开天窗");

        }

    }

    

    static class ElectricCar extends Car {

        private int batteryLevel;

        protected static String vehicleType = "电动汽车";

        

        public ElectricCar(String brand, int doorCount, int batteryLevel) {

            super(brand, doorCount);  // 调用直接父类构造器

            this.batteryLevel = batteryLevel;

            System.out.println("ElectricCar构造器: 电池电量" + batteryLevel + "%");

        }

        

        @Override

        public void start() {

            System.out.println("检查电池电量: " + batteryLevel + "%");

            if (batteryLevel > 20) {

                super.start();  // 调用Car的start()

            } else {

                System.out.println("电量不足,无法启动");

            }

        }

        

        @Override

        public void accelerate(int increment) {

            System.out.println("电动模式加速");

            if (batteryLevel < 10) {

                System.out.println("电量低,限制加速");

                increment = Math.min(increment, 20);

            }

            super.accelerate(increment);  // 调用Car的accelerate()

            batteryLevel -= increment / 10;

            System.out.println("剩余电量: " + batteryLevel + "%");

        }

        

        // 访问祖父类的方法

        public void callGrandparentMethod() {

            System.out.println("直接访问祖父类方法受限,需要特殊处理:");

            

            // 方法1:通过super链

            super.maintenance();  // 调用Car的maintenance()

            

            // 方法2:转型访问

            System.out.println("\n通过转型访问祖父类方法:");

            ((Vehicle)this).maintenance();  // 调用Vehicle的maintenance()

        }

        

        // 多层super调用示例

        public void showAllFields() {

            System.out.println("\n=== 所有层次字段访问 ===");

            System.out.println("当前类字段: ");

            System.out.println("  batteryLevel = " + this.batteryLevel);

            System.out.println("  vehicleType = " + this.vehicleType);

            

            System.out.println("父类(Car)字段: ");

            System.out.println("  doorCount = " + super.doorCount);

            System.out.println("  vehicleType = " + super.vehicleType);

            

            System.out.println("祖父类(Vehicle)字段: ");

            System.out.println("  brand = " + ((Vehicle)this).brand);

            System.out.println("  speed = " + ((Vehicle)this).speed);

            System.out.println("  vehicleType = " + ((Vehicle)this).vehicleType);

        }

    }

    

    // 特殊场景:构造器中的super使用

    static class DatabaseConnection {

        protected String url;

        protected String username;

        

        public DatabaseConnection(String url, String username) {

            this.url = url;

            this.username = username;

            System.out.println("数据库连接创建: " + url);

        }

        

        public void connect() {

            System.out.println("连接到: " + url);

        }

    }

    

    static class PooledConnection extends DatabaseConnection {

        private int poolSize;

        private boolean isPooled;

        

        // 构造器重载,都使用super

        public PooledConnection(String url, String username) {

            this(url, username, 10);  // 调用当前类的其他构造器

        }

        

        public PooledConnection(String url, String username, int poolSize) {

            super(url, username);  // 必须首先调用父类构造器

            this.poolSize = poolSize;

            this.isPooled = true;

            System.out.println("连接池大小: " + poolSize);

        }

        

        @Override

        public void connect() {

            if (isPooled) {

                System.out.println("从连接池获取连接: " + url);

            } else {

                super.connect();  // 调用父类方法

            }

        }

    }

    

    // 测试super的各种用法

    public static void main(String[] args) {

        System.out.println("=== super关键字深度测试 ===");

        

        System.out.println("\n1. 基本super用法:");

        ElectricCar tesla = new ElectricCar("Tesla", 4, 80);

        tesla.start();

        tesla.accelerate(50);

        tesla.maintenance();

        

        System.out.println("\n2. 静态字段访问:");

        tesla.showParentStaticField();

        Car.showType();

        ElectricCar.showType();

        

        System.out.println("\n3. 多层继承访问:");

        tesla.callGrandparentMethod();

        tesla.showAllFields();

        

        System.out.println("\n4. 构造器链测试:");

        PooledConnection conn1 = new PooledConnection("jdbc:mysql://localhost/db", "root");

        conn1.connect();

        

        PooledConnection conn2 = new PooledConnection("jdbc:oracle://server/db", "admin", 20);

        conn2.connect();

        

        System.out.println("\n=== super使用总结 ===");

        System.out.println("1. 构造器中super()必须第一行,且父类要有对应构造器");

        System.out.println("2. super.method()调用父类被重写的方法");

        System.out.println("3. super.field访问父类被隐藏的字段");

        System.out.println("4. 静态成员使用类名访问,而非super");

        System.out.println("5. 多层继承中,super只指向直接父类");

        System.out.println("6. 合理使用super实现代码复用和扩展");

    }

}

```


## 实战应用:设计模式中的字段访问策略


在实际设计模式中合理运用字段访问规则。


```java

// 设计模式中的字段访问最佳实践

public class FieldAccessInDesignPatterns {

    

    // 1. 模板方法模式:合理使用protected字段

    abstract class DataProcessor {

        // 受保护字段,子类可以直接访问

        protected String inputData;

        protected String outputData;

        protected boolean validationPassed;

        

        // 公开的模板方法

        public final void process(String data) {

            this.inputData = data;

            validationPassed = false;

            

            loadData();

            validate();

            if (validationPassed) {

                transform();

                save();

            }

            cleanup();

        }

        

        // 抽象方法,子类必须实现

        protected abstract void loadData();

        protected abstract void transform();

        

        // 钩子方法,子类可以重写

        protected void validate() {

            validationPassed = inputData != null && !inputData.isEmpty();

            System.out.println("基础验证: " + validationPassed);

        }

        

        protected void save() {

            System.out.println("保存结果: " + outputData);

        }

        

        protected void cleanup() {

            inputData = null;

            outputData = null;

            System.out.println("清理完成");

        }

    }

    

    class JsonProcessor extends DataProcessor {

        @Override

        protected void loadData() {

            System.out.println("加载JSON数据: " + inputData);

        }

        

        @Override

        protected void validate() {

            super.validate();  // 调用父类基础验证

            if (validationPassed) {

                validationPassed = inputData.startsWith("{") && inputData.endsWith("}");

                System.out.println("JSON格式验证: " + validationPassed);

            }

        }

        

        @Override

        protected void transform() {

            outputData = inputData.toUpperCase();

            System.out.println("转换JSON数据");

        }

        

        @Override

        protected void save() {

            super.save();  // 调用父类保存

            System.out.println("额外:记录JSON处理日志");

        }

    }

    

    // 2. 建造者模式:使用链式调用和this

    class Computer {

        // 必需参数

        private final String cpu;

        private final String ram;

        

        // 可选参数

        private final String storage;

        private final String graphicsCard;

        private final String powerSupply;

        

        // 私有构造器

        private Computer(Builder builder) {

            this.cpu = builder.cpu;

            this.ram = builder.ram;

            this.storage = builder.storage;

            this.graphicsCard = builder.graphicsCard;

            this.powerSupply = builder.powerSupply;

        }

        

        // 建造者类

        public static class Builder {

            // 必需参数

            private final String cpu;

            private final String ram;

            

            // 可选参数

            private String storage = "512GB SSD";

            private String graphicsCard = "集成显卡";

            private String powerSupply = "500W";

            

            public Builder(String cpu, String ram) {

                this.cpu = cpu;

                this.ram = ram;

            }

            

            public Builder storage(String storage) {

                this.storage = storage;

                return this;  // 返回this支持链式调用

            }

            

            public Builder graphicsCard(String graphicsCard) {

                this.graphicsCard = graphicsCard;

                return this;

            }

            

            public Builder powerSupply(String powerSupply) {

                this.powerSupply = powerSupply;

                return this;

            }

            

            public Computer build() {

                return new Computer(this);

            }

        }

        

        @Override

        public String toString() {

            return String.format("Computer{CPU=%s, RAM=%s, Storage=%s, GPU=%s, PSU=%s}",

                               cpu, ram, storage, graphicsCard, powerSupply);

        }

    }

    

    // 3. 组合模式:使用protected字段实现透明性

    abstract class FileSystemComponent {

        protected String name;

        protected FileSystemComponent parent;

        

        public FileSystemComponent(String name) {

            this.name = name;

        }

        

        public void setParent(FileSystemComponent parent) {

            this.parent = parent;

        }

        

        public abstract void display(String indent);

        

        public String getFullPath() {

            if (parent == null) {

                return name;

            }

            return parent.getFullPath() + "/" + name;

        }

    }

    <"evs.j9k5.org.cn"><"vrb.j9k5.org.cn"><"muy.j9k5.org.cn">

    class File extends FileSystemComponent {

        private long size;

        

        public File(String name, long size) {

            super(name);

            this.size = size;

        }

        

        @Override

        public void display(String indent) {

            System.out.println(indent + "📄 " + name + " (" + size + " bytes)");

        }

    }

    

    class Directory extends FileSystemComponent {

        private List<FileSystemComponent> children = new ArrayList<>();

        

        public Directory(String name) {

            super(name);

        }

        

        public void addComponent(FileSystemComponent component) {

            children.add(component);

            component.setParent(this);  // 设置父引用

        }

        

        @Override

        public void display(String indent) {

            System.out.println(indent + "📁 " + name);

            for (FileSystemComponent child : children) {

                child.display(indent + "  ");

            }

        }

    }

    

    // 4. 装饰器模式:super保持核心功能

    interface Coffee {

        String getDescription();

        double getCost();

    }

    

    class BasicCoffee implements Coffee {

        @Override

        public String getDescription() {

            return "基础咖啡";

        }

        

        @Override

        public double getCost() {

            return 5.0;

        }

    }

    

    abstract class CoffeeDecorator implements Coffee {

        protected Coffee decoratedCoffee;  // 保护字段,子类可访问

        

        public CoffeeDecorator(Coffee coffee) {

            this.decoratedCoffee = coffee;

        }

        

        @Override

        public String getDescription() {

            return decoratedCoffee.getDescription();

        }

        

        @Override

        public double getCost() {

            return decoratedCoffee.getCost();

        }

    }

    

    class MilkDecorator extends CoffeeDecorator {

        public MilkDecorator(Coffee coffee) {

            super(coffee);

        }

        

        @Override

        public String getDescription() {

            return super.getDescription() + " + 牛奶";  // 使用super

        }

        

        @Override

        public double getCost() {

            return super.getCost() + 2.0;  // 使用super

        }

    }

    

    class SugarDecorator extends CoffeeDecorator {

        public SugarDecorator(Coffee coffee) {

            super(coffee);

        }

        

        @Override

        public String getDescription() {

            return decoratedCoffee.getDescription() + " + 糖";  // 直接访问字段

        }

        

        @Override

        public double getCost() {

            return decoratedCoffee.getCost() + 1.0;  // 直接访问字段

        }

    }

    

    // 测试各种设计模式

    public void testDesignPatterns() {

        System.out.println("=== 设计模式中的字段访问 ===");

        

        System.out.println("\n1. 模板方法模式:");

        DataProcessor processor = new JsonProcessor();

        processor.process("{\"name\": \"John\"}");

        

        System.out.println("\n2. 建造者模式:");

        Computer computer = new Computer.Builder("i7", "16GB")

            .storage("1TB NVMe")

            .graphicsCard("RTX 3080")

            .powerSupply("750W")

            .build();

        System.out.println(computer);

        

        System.out.println("\n3. 组合模式:");

        Directory root = new Directory("root");

        Directory documents = new Directory("Documents");

        Directory images = new Directory("Images");

        

        documents.addComponent(new File("report.pdf", 2048));

        images.addComponent(new File("photo.jpg", 5120));

        

        root.addComponent(documents);

        root.addComponent(images);

        root.addComponent(new File("readme.txt", 1024));

        

        root.display("");

        

        System.out.println("\n文件完整路径:");

        for (FileSystemComponent child : java.util.List.of(

            new File("test.txt", 100),

            documents,

            new File("secret.doc", 4096)

        )) {

            documents.addComponent(child);

            System.out.println(child.getFullPath());

        }

        

        System.out.println("\n4. 装饰器模式:");

        Coffee coffee = new BasicCoffee();

        coffee = new MilkDecorator(coffee);

        coffee = new SugarDecorator(coffee);

        coffee = new SugarDecorator(coffee);  // 双份糖

        

        System.out.println("订单: " + coffee.getDescription());

        System.out.println("总价: $" + coffee.getCost());

    }

    

    // 主测试

    public static void main(String[] args) {

        FieldAccessInDesignPatterns demo = new FieldAccessInDesignPatterns();

        demo.testDesignPatterns();

        

        System.out.println("\n=== 字段访问最佳实践总结 ===");

        System.out.println("1. 使用protected字段实现模板方法模式的可扩展性");

        System.out.println("2. 在建造者模式中使用this支持链式调用");

        System.out.println("3. 组合模式中合理设置父引用");

        System.out.println("4. 装饰器模式通过super保持核心功能");

        System.out.println("5. 优先使用访问器方法而非直接字段访问");

        System.out.println("6. final字段提供不变性保证");

        System.out.println("7. 合理使用包可见性进行模块内部通信");

    }

}

```


## 总结


Java继承体系中的成员变量访问遵循明确的就近原则:局部变量优先于当前类字段,当前类字段优先于父类字段。this关键字用于访问当前对象的成员,明确指向当前类定义的字段和方法;super关键字专门用于访问直接父类的成员,特别是在字段被隐藏或方法被重写时。


关键要点:

1. 字段访问没有多态性,基于引用类型在编译时确定

2. 静态字段访问完全基于引用类型或类名

3. 内部类可以通过OuterClass.this访问外部类字段

4. super只能访问直接父类,多层继承需要转型

5. 合理使用protected字段实现模板方法等设计模式


在实际开发中,应优先使用方法访问而非直接字段访问,通过getter/setter方法控制字段访问。在框架和库设计中,合理使用protected可见性可以在保持封装性的同时提供扩展点。理解这些访问规则对于编写清晰、可维护的面向对象代码至关重要。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/19545/viewspace-3110393/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2015-11-01

  • 博文量
    895
  • 访问量
    933672