In our familiar OO language, you can divide data and methods into different levels of access, such as internal, visible, and externally visible, through the access control modifiers private, protected, public, and so on. In this paper, we discuss the topics of encapsulation, type system and contract programming from a more special encapsulation-related example. Let's start with the example:
public class Person {
private int _money;
public void Change(amount){
this._money += amount;
}
public void Exchange(Person p, int amount) {
p._money -= amount;
this._money += amount;
}
}
Based on the assumption that "don't move my money without my permission," The person class takes the variable _money as a private member and provides the change method for public. But the point of contention is that in exchange we can directly access and modify P._money. Please note that the above code is completely legal under the C # compiler, and similar code is also under C + + and Java. When I first contacted this example, I started to wonder if the compiler was right or wrong. Later I thought of a reason "oo encapsulation is based on class rather than object" to convince itself.
Now, there is an updated understanding of this issue, I hope to discuss with you. In the example above, our ideal situation is that the person object itself can directly access its own _money variable, and other person objects cannot be accessed directly. However, the encapsulation implementation of OO must rely on the compiler for static access checks; Since it is static it can only be applied to types and cannot be applied to object instances. Therefore, in the example above, the C # compiler cannot confirm that P and this refer to the same object or to different objects. In this sense, the level of OO encapsulation only to the class is not so much a design consideration as a choice that is not.
On a larger level, this example is not only related to OO encapsulation, but essentially reflects the role and limitations of the program language type system. The type system of program language is a kind of static tracking and checking mechanism, it can guarantee the correctness of the program type, but it can't guarantee the semantic correctness (in the case of the above example, p if and this is the same object, the semantics is correct; otherwise, semantic error). In other words, type correctness can be expressed and examined in a formalized manner through a type system. So how should semantic correctness be guaranteed? Is there a formalized approach? The answer may be as follows:
public class Person {
private int _money;
public void Change(amount){
this._money += amount;
}
public void Exchange(Person p, int amount) {
Assert(this != p);
p.Change(-amount);
this._money += amount;
}
}
To increase assert assertion, we hope to guarantee the correctness of semantics in form. My understanding is that we need a formalized way of guaranteeing semantic correctness. Is this the original intention of the so-called contract programming? Hope the Master Guide!