【问题标题】:Instance variables in Smalltalk Vs javaSmalltalk Vs java中的实例变量
【发布时间】:2014-05-09 02:46:20
【问题描述】:

在 Pharo by Example Book 中,我读到了

Smalltalk 中的实例变量是实例本身私有的。 这与 Java 和 C++ 不同,后者允许实例变量 (也称为“字段”或“成员变量”)被任何人访问 恰好属于同一类的其他实例。

我认为 Java 或 c# 等其他语言也很常见。类的实例不能访问同一类的另一个实例的实例变量。 它是如何只针对 smalltalk 的?

在 Smalltalk 中,同一类的两个实例不能访问彼此的 实例变量,除非该类定义了“访问器方法”

一个实例如何使用访问器方法访问另一个实例的实例变量?

using namespace std;
#include<iostream>
class car {
  private:
    int mileage;
  public:
    car(int); // Constructor
    int odometer();
};

car::car(int m) {
  mileage = m;
}

int car::odometer() {
  return mileage;
}

int main(void) {
  car ford(10000);
  car honda(20000);

  cout<<ford.odometer(); 
  cout<<honda.odometer();
}

在此示例中,福特和本田是同一类 Car 的两个实例。 福特如何使用本田对象的里程,反之亦然?这是我的实际问题。对不起,如果这太天真了

【问题讨论】:

  • 我已经阅读了 Pharo By 示例书中的答案和更多内容。我开始了解到,在 C++ 和 java 中,一个实例可以根据其访问修饰符级别访问其他实例的实例变量,如果是私有的,那么它可以在类中访问,如果是公共的,那么它可以在任何地方访问。但是在 Smalltalk 中,我们不能在课堂上或任何地方做。 java提供的最大封装,C++只到类级别

标签: java encapsulation smalltalk instance-variables getter-setter


【解决方案1】:

这与 Java 和 C++ 不同,后者允许任何其他碰巧属于相同类的实例访问实例变量。

这是真的。

【讨论】:

    【解决方案2】:

    看看这段 Java 代码:

    public class Person {
        Integer wallet = new Integer(100);
    }
    

    并运行 Thief 类:

    public class Thief {
        Person victim = new Person();
    
        public static void main (String[] args) {
            Thief thief = new Thief();
            System.out.println("I take $"+ thief.victim.wallet + " from your wallet!");
        }
    }
    

    结果是:我从你的钱包里取出 100 美元!

    它甚至不必是同一类的实例。

    如果您将 Java 变量声明为 private,同一类的实例仍然可以访问彼此的实例变量。如果你改用上面的例子,一个小偷仍然可以从另一个小偷那里偷东西:

    public class Thief {
        private Integer wallet = new Integer(100);
    
        public Thief victim() {
            Thief victim = new Thief();
            return victim;
        }
    
        public static void main (String[] args) {
            Thief thief = new Thief();
            System.out.println("I take $"+ thief.victim().wallet + " from your wallet!");
        }
    }
    

    这在 Smalltalk 中是不可能的。

    【讨论】:

    • 如果我们在 java 中将钱包声明为私有,那么我们可以实现与在 smalltalk 中相同的功能。不是吗?所以在那本书中他们说在smalltalk中,实例变量的范围默认是私有的。我说的对吗?
    • 在这种情况下,小偷只能从另一个小偷那里偷东西 :) 现在 same class 条件适用。
    • @Sankaran 不,您不能在 Java 中这样声明,同一类的每个其他实例(或通过桥方法的内部类)都可以访问您实例的私有字段/方法。例如,在 Scala 中有 private[this](Smalltalk 方式)和 private(Java 方式)的区别。
    • @MartinW 您的评论是正确的,尽管您的回答似乎是关于默认可见性,而不是关于问题的私密性。
    • @GáborBakos 我扩展了我的答案。但在问题中,private 一词仅与 Smalltalk 变量有关,而不是作为 Java 访问修饰符。
    【解决方案3】:

    我认为 Java 或 c# 等其他语言也很常见。类的实例不能访问同一类的另一个实例的实例变量。它是如何仅针对 smalltalk 的?

    对不起,这种想法是错误的。

    在 Java 中,一个类的实例可以访问同一类的另一个实例的私有字段。

    对于具有两个字段 xy 的类 Pointequals 方法的常见实现(实际上由 Intellij 生成)是:

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
    
        Point point = (Point) o;
    
        if (x != point.x) return false;
        if (y != point.y) return false;
    
        return true;
    }
    

    在这种情况下,当前对象正在直接访问另一个对象 point 的字段,这在 Smalltalk 中是不允许的。

    这在 C# 和许多其他语言中也是允许的。我不确定 Smalltalk 是否真的是唯一不允许它的语言。

    按照惯例,Smalltalk 类的访问器通常与实例变量相同,但您需要实际编写访问器,并且没有直接访问不同实例上的字段的语法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-14
      • 2010-10-01
      • 1970-01-01
      • 2018-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多