【问题标题】:making a class with abstraction is also encapsulation?做一个抽象的类也是封装?
【发布时间】:2015-05-19 13:59:16
【问题描述】:

据说封装是对数据和方法的封装,并隐藏此对象外部不需要的功能(方法和实例变量)

我的问题只是将变量设为私有,而公共是封装?还是做一个有抽象的类也是封装?

例如: 我有开关(电子开关)课在做开或关 为了制作一个 Switch 类,我使用了抽象 我使用抽象封装了 Switch 类,以便我可以映射 电机或灯泡或任何电动仪器

public class Switch {
    private boolean isOff = true;
    private ISwitchListener listener;
    public Switch(ISwitchListener listener) {
        this.listener = listener;
    }
    public void trigger() {
        isOff = !isOff;    
        if(isOff) {
            listener.off();
        } else {
            listener.on();
        }
    }
}

public class Bulb implements ISwitchListener {

    @Override
    public void on() {
        // TODO Auto-generated method stub
        System.out.println("bulb is glittering");
    }

    @Override
    public void off() {
        // TODO Auto-generated method stub
        System.out.println("bulb is not glittering");
    }

}

public interface ISwitchListener {
    public void on();
    public void off();
}

public class Executor {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Switch swt = new Switch(new Bulb()); 
        swt.trigger();          
    }
}

如果我在这里不使用抽象,我会有下面这样的类

public class Switch {
    private boolean isOff = true;
    public void trigger() {

        isOff = !isOff;
        Bulb b =new Bulb();
        if(isOff) {
            b.off();
        } else {
            b.on();
        }
    }
}

当我想将电机映射到开关时,我需要将类更改为 bleow

public class Switch {
    private boolean isOff = true;
    public void trigger() {

        isOff = !isOff;
        Bulb b =new Bulb();
        if(isOff) {
            b.off();
        } else {
            b.on();
        }
    }
}


public class Motor {
    public void on() {
        // TODO Auto-generated method stub
        System.out.println("Motor is rotating");
    }

    public void off() {
        // TODO Auto-generated method stub
        System.out.println("Motor is getting off to rotate");
    }
}

【问题讨论】:

  • 它隐藏了实现而不是功能,隐藏功能没有多大意义。
  • "将变量设为私有和公有" 变量不能两者兼有。 “用抽象做一个类”我不知道这是什么意思。

标签: java oop encapsulation abstraction


【解决方案1】:

你的第一个例子是一个依赖注入的例子 => 你让调用者决定类“Switch”需要哪个具体类来完成它的工作。

实际上它是数据隐藏的“对立面”,因为外界必须知道“Switch”类的一些实现细节。 => 它需要一个 ISwitchListener 的实现

【讨论】:

    【解决方案2】:

    一般来说,不,抽象和封装是两个不同的东西。具体来说,抽象意味着删除对于代码或模型的预期目的不必要的细节。例如,如果您编写一个程序来计算房屋需要多少油漆,您的房屋模型需要包括表面积,但不需要包括地址或院子的大小。 封装意味着隐藏对象或模块的内部工作,以便可以控制和轻松更改对象之间的耦合。如果没有封装,对象的客户端可能会直接引用其内部元素,这意味着如果您修改了对象,则必须更改所有客户端。

    关于代码示例,我认为更好的解决方案是创建一个“可切换”接口并让电机和灯泡实现它。像这样:

    public interface Switchable {
       void on();
       void off();
    }
    
    public class Motor implements Switchable {
        public void on() {
            System.out.println("Motor is rotating");
        }
    
        public void off() {
            System.out.println("Motor is getting off to rotate");
        }
    }
    
    public class Switch {
        private boolean isOff = true;
        private Switchable switchable;
    
        public Switch(Switchable switchable) {
            this.switchable = switchable;
        }
    
        public void trigger() {
            isOff = !isOff;
            if(isOff) {
                switchable.off();
            } else {
                switchable.on();
            }
        }
    }
    

    希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      正如@T 我所说,它可以是一种隐藏方法,例如从 Java 8 中隐藏,您可以在接口中创建默认实现,因此您可以将其隐藏在实现接口的类中。

      但是封装是关于字段(实例变量)隐藏的。创建私有成员(实例变量)并创建 setter 和 getter。您只能通过专用方法达到价值。

      如果你想封装你的方法,你需要处理可访问性(见 default 和 protected 修饰符)。

      所以你的问题的答案是:不。用抽象创建一个类不是封装。

      【讨论】:

        【解决方案4】:

        抽象和封装是相互关联的。您可以说需要抽象来封装系统。 抽象是指客户端系统只需要了解界面中的内容即可。 封装是指模块的客户端无法了解接口中的内容。

        请参考page 获取有关此主题的精彩文章。

        【讨论】:

          猜你喜欢
          • 2017-05-01
          • 2012-05-24
          • 1970-01-01
          • 1970-01-01
          • 2012-02-16
          • 1970-01-01
          • 2019-09-05
          • 1970-01-01
          • 2011-03-03
          相关资源
          最近更新 更多