2010-04-10 35 views
3

从编程角度来看,这是一个非常基本的问题,但由于我处于学习阶段,我认为我最好问这个问题,而不是对该主题有误解或狭隘的认识。语言不可知基本编程问题

所以,如果不知怎的,我搞砸了。

问题

比方说,我有class A,B,C and D现在class A有一些部分的代码,我必须class B,C and D,所以我在class B, class C, and class D

现在延长class A我如何可以访问的功能class A在其他类中,我是否需要创建一个对象class A,并访问class A的函数或在其他类中扩展A,而不是使用内部函数调用该函数s参数。

如果可能的话,我真的很感激,如果有人能解释这个概念与解释逻辑如何流动的代码示例。

实施例中的Java,PHP和.Net,将不胜感激。

回答

2

让我们忘掉C和d,因为它们是相同的B.如果B类扩展类A,那么B类型的对象也是A类型的对象。每当创建B类型的对象时,您还将创建A类型的对象。它应该可以访问A中的所有方法和数据(除非那些标记为私有的方法和数据除外,如果您的语言支持访问修饰语),他们可以直接引用。如果B重写了A的某些功能,那么通常该语言提供了一个调用基类实现(Base.Foo()或其他)的方法。

继承实施例:C#

public class A 
{ 
    public void Foo() { } 
    public virtual void Baz() { } 
} 

public class B : A // B extends A 
{ 
     public void Bar() 
     { 
      this.Foo(); // Foo comes from A 
     } 

     public override void Baz() // a new Baz 
     { 
      base.Baz(); // A's Baz 
      this.Bar(); // more stuff 
     } 
} 

如果,在另一方面,已使用的,而不是继承组合物和B 包含作为一类变量A的一个实例,那么你将需要创建一个A的对象,并通过该实例引用它(公共)的功能。

构成例:C#

public class B // use A from above 
{ 
    private A MyA { get; set; } 

    public B() 
    { 
     this.MyA = new A(); 
    } 

    public void Bar() 
    { 
     this.MyA.Foo(); // call MyA's Foo() 
    } 
} 
+0

你能否详细说明构成部分而不是继承,因为它不是很清楚? – Rachel 2010-04-10 13:17:55

+0

@Rachel:有了作文,你基本上把调用B.Bar()调用为A.Foo()。当A和B不形成“is-a”关系时,这是常用的。例如:福特是一辆汽车,所以福特继承汽车共享实施;但汽车不是一个指导,虽然汽车具有可操纵的属性,但组合更好地反映了这一事实,而不是继承。 – 2010-04-10 14:00:18

+0

@Rachel - 我添加了一个例子。这有帮助吗? – tvanfosson 2010-04-10 14:15:44

2

取决于访问级别(将受到保护或.NET公共),你可以使用类似:

base.method(argumentlist); 

在我的例子base关键字是特定于C#

没有需要一个类A的实例,因为你已经有一个A类继承实例

0

基本上你需要对父类的引用。

在PHP:

parent::example(); 

来源:http://www.php.net/manual/en/keyword.parent.php

<?php 
class A { 
    function example() { 
     echo "I am A::example() and provide basic functionality.<br />\n"; 
    } 
} 

class B extends A { 
    function example() { 
     echo "I am B::example() and provide additional functionality.<br />\n"; 
     parent::example(); 
    } 
} 

$b = new B; 

// This will call B::example(), which will in turn call A::example(). 
$b->example(); 
?> 
+0

你能详细解释一下吗? – Rachel 2010-04-10 13:14:17

+0

从php.net新增的例子有意义吗? – zaf 2010-04-10 13:16:15

+0

现在可以说如果我不是在'class B'中创建一个函数,而不是如何直接调用'class A'中的函数,是否需要在'class B'中创建一个'class A'的实例,然后才能访问'class一个'函数,即使'B类正在扩展'class A' – Rachel 2010-04-10 13:22:00

0

我发现,驯服继承的复杂性的最好办法是确保我只能让B继承A当它真的是超类的一个特例。此时,我可以从B中调用A的方法,就好像它们是B自己的方法一样,如果B已经覆盖了它们,那么我只能假设这必须是有原因的。

当然,对于B执行一个方法来调用A在同一个对象上的实现,通常是很有用的,通常是因为子类正在围绕超类的基本定义包装额外的行为。你这样做的方式因语言而异;例如,在Java中你这样做:

super.methodName(arg1, ...); 
0

下面是一个简单的Java例子:

public class Aclass 
{ 
    public static void list_examples() 
    { 
     return("A + B = C"); 
    } 
} 
public class Bclass extends Aclass 
{ 
    public static void main(String [] args) 
    { 
     System.out.println("Example of inheritance "+list_examples); 
    } 
} 

注意,访问父类中的方法不应该改变。因为您正在扩展,所以不必说parent::或其他任何东西,除非您重写父方法/函数

0

在我看来,延长你的课程可能不是你最好的选择。如果类“B”,“C”和“D”确实是该类的扩展,那么它们只应该扩展类“A”,而不仅仅是访问某种方法。例如,“Huffy”不应该仅仅因为“Huffy”是一个品牌名称而想扩展“BrandNames”,并且您想要访问“BrandNames”的其中一种方法。 “Huffy”应该扩展“Bicycle”并实现一个接口,以便使用“BrandNames”的方法。另外一个好处是(在Java中)可以使用多个接口,但一个类只能被扩展一次。如果在您的示例类“B”中需要访问可以工作的类“A”的方法,但是如果类“C”需要从类“A”和类“B”中访问方法,那么您将有在类“C”中使用接口。