有没有什么办法可以让父类的实例变量直接由其子类(子类)引用?

问题描述:

我屡次搜索谷歌&堆栈溢出的直接答案,但没有找到。这是因为我的问题很容易回答,或者以前没有人问过。经过许多问题读书或多或少提的这个问题后,我得出以下结论:有没有什么办法可以让父类的实例变量直接由其子类(子类)引用?

  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:或许,但你必须承认,他吠叫错了树。这不是通过继承来解决的。 –

简单的构图会的工作:

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

所以接口本质上是指定类应具有哪些功能的类“模具”?除了维护并验证作为构图组成部分的类之外,它们还有其他用途吗? –

使用您的实际情况指出问题的继承,这是很令人费解,当你开始扩展您的服务(组成将是一个你会遇到的问题更现实的做法,但组成配备了一个更大的学习曲线开始,但给人更大的灵活性额外的好处):

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

你把术语 “家长” 和 “孩子” 在一个非常字面意义上的你的例子,但并不总是适用。

只有在类型和子类型之间存在固定关系时才能使用继承。就像“自行车是一辆车”或“长颈鹿是一种动物”。这些关系对于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

这是一个更有趣的独立解决方案,而不是将父母与孩子分开,我将注意到这是一种编程方法(如果我需要实现这样的树状结构)。然而,树状结构并不是我要求编码的东西。 –