java中创建公共类,如何创建“单一调度,面向对象的类”?在julia中,行为类似于具有公共/私有字段和方法的标准Java类...

I read in a book that "you can't create traditional 'classes' in julia with single-dispatch-style methods like obj.myfunc()" ... and I thought that sounded more like a challenge than a fact.

So here's my JavaClass type with public / private fields and methods just for the sheer shock and horror factor of having something ugly like this in Julia, after all the trouble the devs have gone to to avoid it:

type JavaClass

# Public fields

name::String

# Public methods

getName::Function

setName::Function

getX::Function

getY::Function

setX::Function

setY::Function

# Primary Constructor - "through Whom all things were made."

function JavaClass(namearg::String, xarg::Int64, yarg::Int64)

# Private fields - implemented as "closed" variables

x = xarg

y = yarg

# Private methods used for "overloading"

setY(yarg::Int64) = (y = yarg; return nothing)

setY(yarg::Float64) = (y = Int64(yarg * 1000); return nothing)

# Construct object

this = new()

this.name = namearg

this.getName = () -> this.name

this.setName = (name::String) -> (this.name = name; return nothing)

this.getX = () -> x

this.getY = () -> y

this.setX = (xarg::Int64) -> (x = xarg; return nothing)

this.setY = (yarg) -> setY(yarg) #Select appropriate overloaded method

# Return constructed object

return this

end

# a secondary (inner) constructor

JavaClass(namearg::String) = JavaClass(namearg, 0,0)

end

Example use:

julia> a = JavaClass("John", 10, 20);

julia> a.name # public

"John"

julia> a.name = "Jim";

julia> a.getName()

"Jim"

julia> a.setName("Jack")

julia> a.getName()

"Jack"

julia> a.x # private, cannot access

ERROR: type JavaClass has no field x

julia> a.getX()

10

julia> a.setX(11)

julia> a.getX()

11

julia> a.setY(2) # "single-dispatch" call to Int overloaded method

julia> a.getY()

2

julia> a.setY(2.0)

julia> a.getY() # "single-dispatch" call to Float overloaded method

2000

julia> b = JavaClass("Jill"); # secondary constructor

julia> b.getX()

0

Essentially, the constructor becomes a closure, which is how one creates "private" fields and methods / overloading.

Any thoughts? (other than "OMG Why??? Why would you do this??")

Any other approaches?

Any scenarios you could envisage where this might fail spectacularly?

解决方案

While of course this isn't the idiomatic way to create objects and methods in julia, there's nothing horribly wrong with it either. In any language with closures you can define your own "object systems" like this, for example see the many object systems that have been developed within Scheme.

In julia v0.5 there is an especially slick way to do this due to the fact that closures represent their captured variables as object fields automatically. For example:

julia> function Person(name, age)

getName() = name

getAge() = age

getOlder() = (age+=1)

()->(getName;getAge;getOlder)

end

Person (generic function with 1 method)

julia> o = Person("bob", 26)

(::#3) (generic function with 1 method)

julia> o.getName()

"bob"

julia> o.getAge()

26

julia> o.getOlder()

27

julia> o.getAge()

27

It's weird that you have to return a function to do this, but there it is. This benefits from many optimizations like the language figuring out precise field types for you, so in some cases we can even inline these "method calls". Another cool feature is that the bottom line of the function controls which fields are "public"; anything listed there will become a field of the object. In this case you get only the methods, and not the name and age variables. But if you added name to the list then you'd be able to do o.name as well. And of course the methods are also multi-methods; you can add multiple definitions for getOlder etc. and it will work like you expect.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值