2010-03-28 88 views
2

我不確定OOP中的一些事情。面向對象編程如何工作?

如果我有Class1,其中有一些私人的領域,例如private Field field1,使

getField1() { 
    return field1; 
} 

然後我有一些類的構造函數

public Class2 (Field field) { 
    someMethod(field); 
} 

然後我調用的Class2的構造函數CLASS3喜歡:

Class2 cl = new Class2(instanceOfClass1.getField1()); 

而且現在的曲estion:我是否與field1instanceOfClass1someMethod(field)

+1

這是Java或C#或通用OOP? – 2010-03-28 12:35:35

+0

我認爲這並不重要,但它是java。 – venom 2010-03-28 12:40:10

+3

它可能很重要。 Java按值傳遞所有內容,而C/C++可以使用指針和引用。 – 2010-03-28 13:52:52

回答

5

這取決於field是否是一個值或一個參考。當作爲參數傳遞

值類型被複制。引用類型不是;該函數簡單地傳遞一個指向原始值的「引用」,並且它所做的任何更改都會反映到原始值中。

無論是給定類型的值或引用取決於特定的編程語言。一般來說,基本整數和布爾類型通常是值類型,以及其他一切是在空氣中 - 有些語言讓字符串值,和其他人把他們當作參考等

編輯:既然你提到你使用Java,這裏是一個簡短的程序演示值類型和引用類型:

class ClassOne { 
    public int myInt; 
} 

class ClassTwo { 
    public int myInt; 
    public ClassTwo(ClassOne c) 
    { 
     myInt = c.myInt; 
     c.myInt = 3; 
    } 
} 

public class main 
{ 
    public static void main(String[] args) 
    { 
     ClassOne c = new ClassOne(); 
     c.myInt = 1; 
     System.out.println("C1: " + c.myInt); 

     ClassTwo c2 = new ClassTwo(c); 
     System.out.println("C2: " + c2.myInt); 
     System.out.println("C1: " + c.myInt); 

    } 
} 

運行這個程序會給出輸出:

C1: 1 
C2: 1 
C1: 3 

在這個程序中,ClassOne和ClassTwo都包含一個整數字段 - 一個值類型。 ClassTwo在其構造函數中接受一個ClassOne參數 - 一個引用類型,並根據它給出的ClassOne對象的值設置它自己的整數字段,然後更改ClassOne對象的值。

由於類是引用類型,因此在ClassTwo構造函數中更改ClassOne對象會導致原始對象被更改。 (在這裏的主要功能,這是c。)但由於整數是值類型,即使c2在其構造函數中更改c.myInt的值,因爲它預先設置其自己的值,c2.myInt不受影響:它保留原始數字,因爲它被複制而不是被引用。

希望這有助於明確了一點東西。

+0

當我創建ArrayList 和私人MyClass cl;在Java中,都是參考? – venom 2010-03-28 12:43:13

+0

Java中的類類型始終是引用類型。如果在類對象中有一個字段,並且將該字段值傳遞給另一個方法,那麼當它修改了您給它的值時,它將修改原始字段指向的同一個類對象。有些類被設計爲本地不可變,以防止這種混淆 - 字符串是最明顯的例子。字符串一旦創建,就不會改變 - 任何可能改變它們的操作(例如toUpperCase或substring)都會返回一個新的String實例。 – 2010-03-28 13:02:31

2

您正在處理包含在其中的值。如果它是一個可變對象,那麼是的,可以從外部更改Class1實例的狀態,這違反了數據保護原則。這就是爲什麼你應該在返回它們之前複製可變類型。

+0

但是如果我需要完全跟蹤該實例,並且someMethod(field)將該字段放到某個全局查找中?如何通過複製來解決它? – venom 2010-03-28 12:39:44

+0

如果您製作可變對象的深層副本,則對象的任何突變都不會影響副本。 – 2010-03-28 12:41:06

0

我不得不重讀你的問題兩次或三次,以確保我明白你的要求。

總括:

  • 存在被髮送回由它的getField1()方法的Class1其中包含一個字段的屬性(類型字段的?)。
  • 那麼Class2顯然有一個構造函數,它接受Field類型的對象參數並且包含一個使用Field實例觸發本類中的本地方法的方法。
  • 然後,您使用第三個類來實例化Class2,並使用來自Class1實例的getField1()方法使用Field實例對其進行初始化。

在Java的情況下,假設您已經完成了必要的實例化,這意味着在整個過程中將使用Class1中的Field實例。你可以使用System.out.println()(這會給你帶有一系列奇怪數字的@符號)或使用所有對象通用的a.equals(b)方法來驗證。

這裏是關於按值傳遞對象一個有趣的鏈接: http://www.javaranch.com/campfire/StoryPassBy.jsp