加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C和Java中的抽象方法和重写函数

发布时间:2020-12-16 09:37:10 所属栏目:百科 来源:网络整理
导读:在C和 Java或他们尊重的规则中,对覆盖抽象方法有什么限制.必须匹配参数或返回类型.我通常看到只使用返回类型而没有参数实现的抽象函数,是由派生类来指定其余的.它是如何工作的? 解决方法 方法重写必须与它覆盖的父方法具有相同的方法签名,否则不会调用覆盖.
在C和 Java或他们尊重的规则中,对覆盖抽象方法有什么限制.必须匹配参数或返回类型.我通常看到只使用返回类型而没有参数实现的抽象函数,是由派生类来指定其余的.它是如何工作的?

解决方法

方法重写必须与它覆盖的父方法具有相同的方法签名,否则不会调用覆盖.

Java的:

public abstract class AbstractTest {

    public abstract void test() throws Exception;
}

public class ConcreteTest extends AbstractTest {

    @Override
    public void test() throws Exception {

    }
}

如您所见,ConcreteTest(扩展AbstractTest)必须覆盖test().它们具有相同的方法名称,返回类型和方法参数.子类可以省略从基类抛出的异常并抛出自己的异常.子类还可以添加其他(未)检查的异常.

正如Peter Lawrey所提到的,java接口方法是隐式抽象方法(参见我在Java Abstract Interface的SO问题).

这里至关重要的是在这种情况下方法可见性不会改变(因为它是分层可见性,即私有 – >受保护 – >公共).这是有效的:

public abstract class AbstractTest {

    protected abstract void test() throws Exception;
}

public class ConcreteTest extends AbstractTest {

    @Override
    public void test() throws Exception {

    }
}

(父类具有受保护的方法,子类可以覆盖相同的方法,只有2个可见性选择:protected或public).

另外,假设你有

public class B {

}

public class D extends B {

}

public abstract class Base {

    public abstract B foo();
}

public class Derived extends Base {

    @Override
    public D foo() {
        // TODO Auto-generated method stub
        return new D();
    }

}

您将看到Derived返回D而不是B.为什么会这样?这是因为派生类遵循与父类相同的签名,派生类的返回类型是父类的返回类型的子类型.

所以,我可以这样:

Base pureBase = new Derived();
B b = pureBase.foo(); //which returns class D

if (b instanceof D) {
   //sure,it is,do some other logic
}

在C中,您可以使用Covariant Return类型获得类似的效果

C

class AbstractTest {
public:
    virtual void test() = 0;
};


class ConcreteTest : AbstractTest {
public:
    void test() {
        //Implementation here...
    }
};

在C中,具有纯虚函数的类(以a = 0结尾的虚函数)被称为抽象类.子类(在C中,类扩展名由:)分隔,覆盖纯虚方法(除了它不包含= 0).它具有与其父类相同的签名.

回到我们的Java示例,假设您有:

class B {

};

class D : B {

};

class Base {
public:
    virtual B* foo() = 0;
}

class Derived : Base {
public:
    D* foo() {
        return new D();
    }
}

这里完成了相同的推理(如java中所述).协变返回类型也适用于受保护和私有继承.更多关于Covariant return types.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读