public class User{
private String name;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public static void main(String[] args){
User user = new User();
user.setName("Michael");
System.out.println(user.getName());
}
}
I suppose ugly is a subjective term. Perhaps verbose is the better term. Many other languages offer syntax that is simplified, but without losing encapsulation. For example, here is similar code in Ruby:
class User
attr_accessor :name
def name=(name)
puts "setter called"
@name = name
end
end
user = User.new
user.name = "Michael" #setter called
puts user.name #Michael
In the above code, the getter and setter are both generated by the attr_accessor method. The syntax makes it seem like the internal state is exposed directly, but there really are methods being generated and invoked. To demonstrate this, I chose to override the setter and added in some extra code to let you know it had been called. Ruby is a very powerful language, and its meta-programming (i.e. code that writes more code for you, like the attr_accessor method above) are renowned. However, it is hardly the only language that does properties like this. Good 'ol Python can do it too:
class User(object):
def getname(self):
return self.__name
def setname(self, name):
print "setter called"
self.__name = name
name = property(getname, setname)
user = User()
user.name = "Michael" #setter called
print user.name #Michael
Not quite as succinct or as elegant as Ruby, but it works. Slick properties were added to Objective-C not too long ago as well:
@interface User:NSObject{
NSString* name;
}
@property (copy) NSString* name;
@end
@implementation User
@synthesize name;
- (void) setName:(NSString *)name{
[self.name autorelease];
self.name = [name copy];
}
@end
The header file makes this more verbose, as well as the memory management. Objective-C has a garbage collector, but only for its desktop profile. You have to manually manage the memory if you are writing Objective-C for an iPhone application.
ActionScript 3.0, which is based on the now defunct EcmaScript 4.0 specification also has properties. The syntax is a little verbose
class Person{
private var _name:String;
public function get name(){
return _name;
}
public function set name(name:String){
trace("Setter called");
_name = name;
}
}
Note that you have to define both the get and set functions. This gives you the "dot syntax", i.e. you can do something like myPerson.name = "Michael". Scala is similar:
class Person{
private var _name:String = null
def name:String = _name
def name_=(name:String){
println("setter called")
_name = name
}
}
object App{
def main(args:Array[String]){
val person = new Person
person.name = "Michael"
println(person.name)
}
}
Scala can generate the getter/setter for you, but you cannot override them. So if all I wanted was the default behavior, nothing extra, I coudl just do
class Person{
var name:String=null
}
object App{
def main(args:Array[String]){
val person = new Person
person.name = "Michael"
println(person.name)
}
}
There is no way to override the methods that Scala generates for you. Even if you subclass Person, you cannot alter the generated getter/setter methods.
No comments:
Post a Comment