2017-04-18 90 views
-2

我屢次搜索谷歌&堆棧溢出的直接答案,但沒有找到。這是因爲我的問題很容易回答,或者以前沒有人問過。經過許多問題讀書或多或少提的這個問題後,我得出以下結論:有沒有什麼辦法可以讓父類的實例變量直接由其子類(子類)引用?

  1. 一個父類的對象和兒童類的對象是相互完全獨立,這意味着兒童類的對象不創建一個單獨的父類對象,而是一個自包含的對象。

  2. 通過利用反射,您可以使用一種方法(許多人重新發布而不歸因於上載代碼的在線教程),該方法將一個對象的超類的所有字段(如果有的話)複製到另一個。這個方法是一次性的,並且實際上並沒有改變變量的引用(這意味着如果2個對象,一個父類和一個子類,通過該方法,即使父類的變量內容將被複制到子類,如果父類的變量更改子類的變量將保持不變)。

  3. 通過利用靜態變量和變量變量的方法,這些變量在運行時在所有類中共享,這意味着所有對象共享相同的變量。這不是我想要達到的。易變變量並不是一個解決方案,因爲它們主要被實現Runnable用於它們的Thread實例的類所使用(並且,我認爲,由於它們存儲在RAM中而不是通過CPU傳遞,所以在所有類中共享)。

我們實際上解釋我的問題,我想達到的目標是有一定的少兒班從單一的父類幹,而且有多個這樣的「我們的家庭卻更」。例如,假設父類存儲包含名稱的字符串。我想要3個孩子從父母的字符串名稱是「喬治」和其他3個孩子源於其父母的字符串名稱是「尼克」。當存儲在「喬治」父類中的字符串從「喬治」變爲「帕特里克」時,我希望將它改爲它的孩子,而不是「尼克」的孩子。

可以這樣做嗎?

如果這是一個新手問題,我非常抱歉,但我在單身大學的第一年,我們仍在學習如何循環,功能等工作。

編輯:

代碼展示我的例子:

public class Parent { 
    private String name; 
    public Parent(String name) { 
     this.name = name; 
    } 
    public void changeName(String newName) { 
     name = newName; 
    } 
    public String getName() { 
     return name; 
    } 
    public void complexMethod() { 
     System.out.println(name); 
    } 
    //Multiple other complex methods here. 
} 

public class Child extends Parent { 
    public Child(Parent p) { 
     //Code which gets the memory references from the p Parent and stores them. 
    } 
} 

public class mainApp { 
    public static void main(String[] cmdArgs) { 
     Parent George = new Parent("George"); 
     Parent Nick = new Parent("Nick"); 
     Child a = new Child(George); 
     Child b = new Child(George); 
     Child c = new Child(Nick); 
     George.changeName("Patrick"); 
     System.out.println(a.getName());//Prints "Patrick" 
     System.out.println(b.getName());//Prints "Patrick" 
     System.out.println(c.getName());//Prints "Nick" 
     a.complexMethod();//Calls complex method of Parent class with the String "Patrick" stored on the Parent class. 
     c.complexMethod();//Calls complex method of Parent class with the String "Nick" stored on the Parent class. 
    } 
} 

編輯2:

什麼,他們要求我們做,直接翻譯詞對詞與損失儘可能少的一個片段作爲上下文可能:

「服務提供商」類「提供兩種形式的服務,移動 互聯網和移動蜂窩網絡。此外,蜂窩網絡被進一步分成兩部分,一個蜂窩網絡,其基於用戶已簽署卡合同 的事實以及基於用戶 已經簽署了一個事實而起作用的蜂窩網絡移動合同。所有的服務都存儲在 「收藏」(他們是直接引用到ArrayList的,因爲他們 問導入特定庫)是一流的「服務提供商 」內。 (關於功能的詳細信息在這裏)

事實是,服務提供商構造函數接受和存儲包含服務提供者的名稱的String,這意味着如果我們要爲同一個供應商,我們創建多種類型的服務浪費國際海事組織不好編程的記憶。 (實際上他們要求我們存儲多種類型的服務爲同一供應商)

+1

您看起來像是一個[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem),您在那裏綁定以獲得使用繼承的代碼解決方案,而最好的解決方案可能根本不使用繼承,而是組合。你所說的這些「孩子」應該被看作是一個集合樹中的節點對象,而不是子類。 –

+0

他只是學習循環,不要打他的作文:p – Neilos

+0

@ neilos:或許,但你必須承認,他吠叫錯了樹。這不是通過繼承來解決的。 –

回答

-1

簡單的構圖會的工作:

public class LeaderFollower { 
    public static void main(String[] cmdArgs) { 
     Leader george = new Leader("George"); 
     Leader nick = new Leader("Nick"); 
     Follower a = new Follower(george); 
     Follower b = new Follower(george); 
     Follower c = new Follower(nick); 
     george.setName("Patrick"); 
     System.out.println(a.getName());//Prints "Patrick" 
     System.out.println(b.getName());//Prints "Patrick" 
     System.out.println(c.getName());//Prints "Nick" 
    } 
} 

class Leader { 
    private String name; 

    public Leader(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 


} 

class Follower { 
    private Leader leader; 

    public Follower(Leader leader) { 
     this.leader = leader; 
    } 

    public String getName() { 
     return leader.getName(); 
    } 
} 

的跟隨者擁有領袖它用來定義其名稱屬性的實例。因此,這是不是讓追隨者堅持「是一個」繼承的規則來解決,而是「有-A」的組成規則 - 它「一個」領導者。在OOP-Ese中,追隨者將其名稱屬性代表其包含的領導實例。

你也可以在這個混合中使用接口。例如:

public class LeaderFollower { 
    public static void main(String[] cmdArgs) { 
     Nameable george = new Leader("George"); 
     Nameable nick = new Leader("Nick"); 
     Nameable a = new Follower(george); 
     Nameable b = new Follower(george); 
     Nameable c = new Follower(nick); 
     george.setName("Patrick"); 
     System.out.println(a.getName());// Prints "Patrick" 
     System.out.println(b.getName());// Prints "Patrick" 
     System.out.println(c.getName());// Prints "Nick" 
    } 
} 

interface Nameable { 
    String getName(); 
    void setName(String name); 
} 

class Leader implements Nameable { 
    private String name; 

    public Leader(String name) { 
     this.name = name; 
    } 

    @Override 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 

class Follower implements Nameable { 
    private Nameable leader; 

    public Follower(Nameable leader) { 
     this.leader = leader; 
    } 

    @Override 
    public String getName() { 
     return leader.getName(); 
    } 

    @Override 
    public void setName(String name) { 
     leader.setName(name); 
    } 
} 
+0

我會將此答案標記爲如果沒有給出其他答案,則應該正確,因爲這實際上是我想實現的目標,並且已經實施了基於此模型的解決方案。這只是我想看看大學是否真的要求我們做一些「不可能的事情」。直接翻譯片段添加到原始文章。 –

+0

@AlexPapageorgiou:您的*確切*單詞對單詞的要求是什麼?也許你誤解了他們? –

+0

所以接口本質上是指定類應具有哪些功能的類「模具」?除了維護並驗證作爲構圖組成部分的類之外,它們還有其他用途嗎? –

1

使用您的實際情況指出問題的繼承,這是很令人費解,當你開始擴展您的服務(組成將是一個你會遇到的問題更現實的做法,但組成配備了一個更大的學習曲線開始,但給人更大的靈活性額外的好處):

public abstract class ServiceProvider { 

    private String providerName; 
    private String clientName; 

    public ServiceProvider(String providerName, String clientName) { 
    this.providerName = providerName; 
    this.clientName = clientName; 
    } 

    public String getProviderName() { 
    return this.providerName; 
    } 

    public String getClientName() { 
    return this.clientName; 
    } 

    boolean validateContract(); 

} 

public class MobileInternetProvider extends ServiceProvider { 

    public MobileInternetProvider(String providerName, String clientName) { 
    super(providerName, clientName); 
    } 

    public boolean validateContract() { 
    return ContractService.validateMobileInternetProvider(this.getClientName()); 
    } 

} 

public abstract class MobileCellularProvider extends ServiceProvider { 

    public MobileCellularProvider(String providerName, String clientName) { 
    super(providerName, clientName); 
    } 

    public boolean validateContract() { 
    return ContractService.validateMobileCellularProvider(getContractNumber()); 
    } 

    String getContractNumber(); 

} 

public class MobileCellularProviderCardContract extends MobileCellularProvider { 

    public MobileCellularProviderCardContract(String providerName, String clientName) { 
    super(providerName, clientName); 
    } 

    public String getContractNumber() { 
    MobileContractService.getCardContractNumber(this.getClientName()); 
    } 

} 

public class MobileCellularProviderMobileContract extends MobileCellularProvider { 

    public MobileCellularProviderMobileContract(String providerName, String clientName) { 
    super(providerName, clientName); 
    } 

    public String getContractNumber() { 
    MobileContractService.getMobileContractNumber(this.getClientName()); 
    } 

} 

你會再使用這樣的:

ArrayList<ServiceProvider> serviceProviders = new ArrayList<>(); 
serviceProviders.add(new MobileCellularProviderMobileContract(ProviderDef.PROVIDER_1, "Client 1")); 
serviceProviders.add(new MobileCellularProviderMobileContract(ProviderDef.PROVIDER_1, "Client 2")); 
serviceProviders.add(new MobileCellularProviderCardContract(ProviderDef.PROVIDER_1, "Client 3")); 
serviceProviders.add(new MobileInternetProvider(ProviderDef.PROVIDER_1, "Client 4")); 
serviceProviders.add(new MobileInternetProvider(ProviderDef.PROVIDER_2, "Client 1")); 

原來的答案

當一個子類實例化,它擁有超類的領域,因此有更新的子類之間沒有區別name領域和更新父name場...有實例中的唯一一個場。

所以,當你說:

例如,讓我們說,父類存儲其中包含名稱的字符串。我想要3個孩子從父母的字符串名稱是「喬治」和其他3個孩子源於其父母的字符串名稱是「尼克」。當存儲在「喬治」父類中的字符串從「喬治」變爲「帕特里克」時,我希望將它改爲它的孩子,而不是「尼克」的孩子。

這並沒有真正意義。

你的問題的標題說

有沒有辦法對父類的實例的變量,其子女(子類)直接引用?

答案是肯定的!但是,你描述你的問題是不相關的問題的標題

+0

downvotes護理解釋? – Neilos

+0

我認爲dowvotes是指的措辭。 「更新子類」字段和更新超類字段......它們是相同的東西「使得它看起來像它們實際上是它們不是的同一個內存引用,至少據我所知。 –

+0

我的答案有點模棱兩可,我想說的是實例化的類既是它本身的一個實例,也是它的超類,因此如果一個超類有一個字段'name',那麼子類將*繼承這個字段,它可能無法訪問它,但實例只有一個引用,而不是子類和超類的單獨引用,這是我認爲你在你的問題中暗示的,這是沒有意義的。 – Neilos

1

你把術語 「家長」 和 「孩子」 在一個非常字面意義上的你的例子,但並不總是適用。

只有在類型和子類型之間存在固定關係時才能使用繼承。就像「自行車是一輛車」或「長頸鹿是一種動物」。這些關係對於Bicycle和長頸鹿的每個實例都是一樣的。但是你所描述的不是這樣的。

對於您的情況,您可以使用組合來建模。

  • 每個Person有一個name
  • Personparent(這可能會留下null表示 「不知道」 或 「不關心」)
  • 每個Person具有零個或多個children
class Person { 
    String name; 
    Person parent; 

    Person(String name, Person parent) { 
     this.name = name; 
     this.parent = parent; 
    } 

    // etc (getters, setters) 
} 

public class MainApp { 
    public static void main(String[] cmdArgs) { 
     Person george = new Person("George", null); 
     Person nick = new Person("Nick", null); 
     Person a = new Person("a", george); 
     Person b = new Person("b", george); 
     Person c = new Person("c", nick); 
     // etc. 
    } 
} 
+0

................確切如此 –

+0

這是一個更有趣的獨立解決方案,而不是將父母與孩子分開,我將注意到這是一種編程方法(如果我需要實現這樣的樹狀結構)。然而,樹狀結構並不是我要求編碼的東西。 –

相關問題