簡體   English   中英

Scala類是否具有像Python一樣的“自我”?

[英]Do scala classes have “self” like Python?

例如,如果我有

object Solution {
    class myClass(A: Array[Int]){
        val something: Int = A.length;
        val another: Int = something/2;
        val someName = "blah"
 ...
 ...

這些變量僅在myClass的特定實例中“存在”,還是在所有對象之間共享“類范圍”變量? 如果是后者,如何使這些變量僅對象化?

是的,這是實現this ,像在Java或C ++。 您不必像在python中那樣在方法調用中顯式傳遞它。

然后,在示例中創建的是實例變量,也稱為成員。 它們屬於該類的實例,即它們不在所有相同類的所有對象上共享( 類變量 )。 對於后者,您可能需要使用伴隨方案

最后,您可能想更多地了解scala,例如此處的本教程 ,或者由@IanAuld提供給python開發人員的書,或者在scala的創建提供的Coursera上運行scala課程

和順便說一句,歡迎堆棧溢出!


編輯:

因此,在Scala中我在此處設置的方式是實例變量,而如果我在Python中執行了相同的通用方法(就放置而言),它們將是類變量? 還是您說我必須在某處添加“ this”以使它們成為實例變量?

我知道您在哪里感到困惑。 Python和Scala在面向對象編程的方法上有很大不同。 首先讓我們談談python:

蟒蛇

Python的設計思想是類(和模塊,btw)是dict ,在早期版本的python中,您甚至可以通過myclass.__dict__成員訪問該類的成員,即使今天該dict是“隱藏的”通過實現,仍然可以通過getattrsetattr訪問。

這個想法是python如何使用類的中心,因為一切都是通過猴子補丁完成的,即在運行時更改和實際定義類定義。

class Foo:
    pass
foo = Foo()
foo.bar = 1
print(foo.bar)

python基本的另一件事是一切都是顯式的。 這就是為什么當你聲明一個方法,你傳遞當前類作為參數傳遞給方法的明確的參考:

class Foo:
    def foobar(self):
        self.bar = 1
print(foo.bar)

但這實際上等效於:

class Foo:
    pass
def foobar(self):
    self.bar = 1
foo = Foo()
foobar(foo)
print(foo.bar)

以下行為很好地說明了猴子修補的含義:

class Foo:
    def foobar(self):
        print(self.bar)
foo = Foo()
foo.bar = 1
foo.foobar() # prints 1

因此,當您實際在python中定義成員時,您真正要做的就是用新成員來修補當前實例。

現在,當您執行類實例時,如果我們使用我告訴您的dict表示形式,您實際上的行為如下所示:

Foo = dict(a=1, b=[2]) # class definition with class variables
foo = Foo.copy()       # create instance
foo['b'].append(3)     # use a class variable's instance
print(Foo['b']) # prints: [2,3]

總而言之,python對OOP有一種非常特殊的方法,它完全基於類的行為有點像dict的思想,並且它們應該被猴子修補以定義(這就是為什么在創建類時,約定是在構造函數中聲明所有成員)。 這就是為什么python不被視為“純”面向對象語言(這只是該語言的一種屬性,而不是一種限定條件)的原因。

斯卡拉

Scala被定義為一種純功能性和純面向對象的語言。 而且該語言的這兩個屬性使其與python非常非常不同。 我不會深入解釋函數式編程,但是我強烈建議您學習一門課程並閱讀有關它的書籍,並充分掌握Scala的知識。

因此,在Scala中定義類時,可以執行以下操作(示例由我鏈接的教程提供):

class Square {
    var x: Double = 0
    var y: Double = 0
    var width: Double = 0
    var height: Double = 0
    def area(): Double = width * height
}

因此,在這里您定義了實例變量,並為它們提供了一個“默認”值,這是您在__init__()構造函數中的python中定義的值。 然后定義一個方法。

但是由於scala是功能性的,因此您可以在類定義中再讀一遍:

class Square(
    private var x: Double,
    private var y: Double,
    private var width: Double,
    private var height: Double
  ) {
    def area(): Double = width * height
  }

Square是一個接受參數的函數,並返回一個實例,該實例具有在該函數范圍內定義的方法。 因此,外部“函數”實際上是構造函數,內部函數是方法。

現在,scala中不存在任何實際的類變量,為此,您可能更喜歡使用配套設計模式(請參見有關SO的答案鏈接)。

但順便說一句,因為您在示例中使用的someName變量的屬性:

class myClass(A: Array[Int]){
    val something: Int = A.length;
    val another: Int = something/2;
    val someName = "blah"

您的someName變量是不可變的。 這意味着您不能在實例中對其進行修改,因此,所有實例都相同。 所以以某種方式,它看起來像類變量,即使不是,它們實際上是實例變量。

就像我在python中的dict示例一樣,這也不是完全准確的,因為關於這些機制還有更多的知識要知道-我什至沒有在這方面做鋪墊,但是它的目的是證明Scala(一種功能強大的功能)之間的巨大差異/ object語言和python-一種🐒-patching/目標語言。

現在從過程范式語言邁向功能性語言邁出了一大步,感覺就像是在學習重新開發,但這絕對是值得的,因為它會教給您一種不同的程序思維方式,不僅您學習了新語言和新范式,但是通過更好的實踐和更多地關心打字,它也將使您以已經知道的語言更好地發展。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM