如何停止将派生类对象分配给基类指针 [英] how to stop assigning derived class object to base class pointer

查看:71
本文介绍了如何停止将派生类对象分配给基类指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有四个课程如下



  class  Base 
{
public void printf()
{
Console.WriteLine( 我来自基地!!!);
}
}

class DerivedA:Base
{
public void printf()
{
Console.WriteLine( 我来自A !!!);
}
}

DerivedB:基本
{
public void printf()
{
Console.WriteLine( 我来自B !!!);
}
}

class testProgram
{
public void print(Base baseClass)
{
baseClass.printf();
}
}





我的目标是当我在第4行执行以下代码时,它必须给我错误。



 testProgram tP =  new  testProgram(); 
tP.print(baseClass);
tP.print(derivedA);
tP.print(derivedB);





我需要做些什么改变????

提前谢谢

解决方案

您的测试程序'printf方法获取Type Base的单个参数:因此,即使将A类或B类的有效实例传递给它,它也是如此将始终调用在Base中定义的'printf方法。



通过声明Type Base的参数,您基本上将A或B的实例向下转换为Type基础。



使用最少的代码可以避免这种情况的一种方法是使参数Type为动态并让你为工作做每种类类型的正确方法:

  //  假设您已创建这些实例: 
public Base baseClass = new Base();
public DerivedA derivedA = new DerivedA();
public DerivedB derivedB = new DerivedB();

public class testProgram
{
public void print( dynamic baseClass)
{
baseClass.printf();
}
}

但是,你需要为使用'动态付出代价,而且,在你进行C#编程更先进之前,你可能要等到你完全理解'如何'动态(后期绑定)在您的代码中使用它之前有效。



另一种可以使代码使用正确类型的方法是评估类型:

  public   class  testProgram 
{
public void print(Base baseClass)
{
if (baseClass DerivedA)
{
(baseClass as DerivedA).printf();
}
else if (baseClass DerivedB)
{
// 取消注释以调用printf方法在DerivedB
// (baseClass为DerivedB).printf();

// 抛出错误? ......但是,为什么?
// 发表评论out不抛出错误
throw new InvalidProgramException( DerivedB不打印);
}
else
{
baseClass.printf();
}
}
}

但是,如果您不想使用它,为什么在类DerivedB中有'printf方法?



我建议您在想要隐藏基类中定义的方法时,在创建派生类中的方法时考虑使用'新方法修饰符:

  public   class  DerivedA:Base 
{
public new void printf()
{
Console .WriteLine( 我来自派生A !!!);
}
}

public class DerivedB:基本
{
公共 void printf()
{
Console.WriteLine( 我来自派生B !!!);
}
}

使用'new(即使这里没有必要:你会收到编译器警告,但不是错误)会使意图你的代码清楚。请参阅:[ ^ ]。


嗨会员,



你不能停止将派生对象分配给它的基类指针。这就是OOP的本质...



所以你的问题没有意义。



如果BillWoodruf正确地猜测你真正想要什么,我想补充说你可以使用这样的代码(也许还可以看看 http://msdn.microsoft.com/en-us/library/ms173153.aspx [ ^ ])



 使用系统; 

命名空间 ConsoleApplication4
{
class Base
{
public virtual void printf()
{
Console.WriteLine( 我来自基地!! !);
}
}

class DerivedA:Base
{
public 覆盖 void printf()
{
Console.WriteLine( 我来自A !!!);
}
}

DerivedB:基本
{
public 覆盖 void printf()
{
Console.WriteLine( 我来自B!);
}
}

class testProgram
{
public void print(Base baseClass)
{
baseClass.printf();
}
}

class 计划
{
static void Main( string [] args)
{
Base baseClass = new Base();
DerivedA derivedA = new DerivedA();
DerivedB derivedB = new DerivedB();

testProgram tP = new testProgram();
tP.print(baseClass);
tP.print(derivedA);
tP.print(derivedB);

Console.ReadKey();
}
}
}





快乐学习!


I have four classes as follow

class Base
    {
        public void printf()
        {
            Console.WriteLine("I am fro base !!!");
        }
    }

class DerivedA : Base
    {
        public void printf()
        {
            Console.WriteLine("I am fro derived A !!!");
        }
    }

class DerivedB : Base
    {
        public void printf()
        {
            Console.WriteLine("I am fro derived B !!!");
        }
    }

class testProgram
    {
        public void print(Base baseClass)
        {
            baseClass.printf();
        }
    }



my aim is when I execute following code in line 4 it must give me error.

testProgram tP = new testProgram();
 tP.print(baseClass);
 tP.print(derivedA);
 tP.print(derivedB);



What changes I need to do ????
thanks in advance

解决方案

Your test program 'printf method gets a single parameter of Type Base: so, even if a valid instance of Class A, or Class B, is passed to it, it will always call the 'printf method defined in Base.

By declaring the parameter of Type Base, you essentially down-cast the instance of A, or B, to Type Base.

One way you could avoid this, with minimum code, would be to make the parameter Type 'dynamic and let that "do the work" for you of calling the right method for each Class Type:

// assuming you have these instances created:
public Base baseClass = new Base();
public DerivedA derivedA = new DerivedA();
public DerivedB derivedB = new DerivedB();

public class testProgram
{
    public void print(dynamic baseClass)
    {
        baseClass.printf();
    }
}

However, you pay a price for using 'dynamic, and, until you are more advanced in C# programming, you may want to wait until you fully understand how 'dynamic (late binding) works before using it in your code.

Another way you can make your code use the "right Type" is to evaluate the Type:

public class testProgram
{
    public void print(Base baseClass)
    {
        if (baseClass is DerivedA)
        {
            (baseClass as DerivedA).printf();
        }
        else if (baseClass is DerivedB)
        {
            // uncomment this to call the printf method in DerivedB
            //(baseClass as DerivedB).printf();

            // throw an error ? ... but, why ?
            // comment this out to not throw the error
            throw new InvalidProgramException("DerivedB don't print"); 
        }
        else
        {
            baseClass.printf();
        }
    }
}

But, why have a 'printf Method in Class DerivedB if you don't want to use it ?

I suggest you consider using the 'new method modifier when you are creating methods in derived classes when you wish to "hide" the method defined in the base Class:

public class DerivedA : Base
{
    public new void printf()
    {
        Console.WriteLine("I am from derived A !!!");
    }
}

public class DerivedB : Base
{
    public new void printf()
    {
        Console.WriteLine("I am from derived B !!!");
    }
}

Using 'new (even though not necessary here: you'll get a compiler warning, but, not an error) makes the intent of your code clear. See: [^].


Hi Member,

You can't stop assigning a derived object to it's base class pointer. That's the nature of OOP...

So your question doesn't make sense.

If BillWoodruf was right in guessing what you really want, I'd like to add that you could use code like this (maybe also have a look at http://msdn.microsoft.com/en-us/library/ms173153.aspx[^] )

using System;

namespace ConsoleApplication4
{
    class Base
    {
        public virtual void printf()
        {
            Console.WriteLine("I am fro base !!!");
        }
    }

    class DerivedA : Base
    {
        public override void printf()
        {
            Console.WriteLine("I am fro derived A !!!");
        }
    }

    class DerivedB : Base
    {
        public override void  printf()
        {
            Console.WriteLine("I am fro derived B !!!");
        }
    }

    class testProgram
    {
        public  void print(Base baseClass)
        {
            baseClass.printf();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Base baseClass = new Base();
            DerivedA derivedA = new DerivedA();
            DerivedB derivedB = new DerivedB();

            testProgram tP = new testProgram();
            tP.print(baseClass);
            tP.print(derivedA);
            tP.print(derivedB);

            Console.ReadKey();
        }
    }
}



Happy learning!


这篇关于如何停止将派生类对象分配给基类指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆