其实例是在下面的代码行中创建的

时间:2014-09-12 07:33:01

标签: c# oop inheritance interface

this question的答案说“你没有创建接口的实例......”我想知道它是否属实。

任何人都可以告诉我在下面的代码行中创建了哪些实例?为什么?

BaseClass b= new Child();

 BaseInterface bi= new Child();

编辑:我问的是关于C#.net语言。如果实例是创建了child()。为什么视觉工作室的intellisense会在按下时显示基础成员?

4 个答案:

答案 0 :(得分:4)

创建的实际对象是Child类的实例

“up-cast”只是相同子对象实例的不同视图

静态类型语言基于表达式类型限制操作,而不是表达式求值的实际对象的类型。因此,IntelliSense将仅显示适用于b的BaseClass和bi的BaseInterface的方法。

这也是Object o = new Child()这样的东西有效的原因,即使只能调用Object上定义的方法o,这是一个表达式,类型为Object

实际对象 一个Child的事实可以这样证明:

Child c = new Child();
BaseClass b = c;
BaseInterface bi = c;
c.GetType() == typeof(Child)     // => true
object.ReferenceEquals(c, b)     // => true
object.ReferenceEquals(c, bi)    // => true

答案 1 :(得分:2)

这是一个非常基本的问题,但却非常非常重要。但我不确定这个网站是获得答案的最佳媒介(更重要的是,了解它)。尝试在某处学习OOP课程,或者寻找详细介绍它的在线演示文稿。

简短回答

运行时类型和静态类型是两个非常不同的东西。

更长的答案:

在静态类型语言中,如C#(或java,或F#或其他一些),变量始终具有静态类型。静态类型是编译器证明变量的类型,因为你告诉它它是,或者因为它推断了它(例如在var或lambda参数的情况下)。

一些例子:

int i; //i is of type int
BaseClass b; //b is of class BaseClass
IEnumerable<int> list; //list implements interface IEnumerable<int>
var s = "foo"; //s is inferred to be of type string

这是静态输入。它表示变量属于给定类型。它并不意味着变量中的对象是这种类型(对于接口来说甚至都没有意义!),它只是意味着编译器已经证明内部对象可以赋值给这种类型(这正好意味着它可以是放入该类型的变量/字段中。)

对比运行时类型。运行时类型是实例的实际类型。它只是一个运行时的东西,编译器无法访问它。这是有效的。

静态进行方法和属性调用时,只能从静态类型调用属性和方法。只是因为它是编译器可以知道的唯一类型。当你写作

BaseInterface bi= new Child();

您有效地告诉编译器“我要求您忘记此对象是Child,将其视为BaseInterface”。这正是编译器的作用:您无法访问特定于Child类的bi的成员。

事实上,这种分配只是进行两种截然不同的操作的简短方法。它与

相同
BaseInterface bi; // I create a "bi" variable. Its static type is BaseInterface
bi = new Child() // Instanciate an object of runtime type Child and assign it to the bi variable

为变量赋值不会改变其静态类型。

答案 2 :(得分:2)

BaseClass b = new Child(); - new Child()调用类Child的构造函数初始化对象(创建新实例),引用类型为Base类。 因此,如果BaseClass a具有baseClassMet()并且类Child()具有aditional方法childMet(),则可以调用仅在BaseClass中定义的方法。

BaseInterface bi = new Child();首先使用接口,您无法直接实例化接口。您可以为接口分配实现该接口的类。

所以在这种情况下,我们假设Base接口有一个方法定义void interfMet(); 如您所知,在实现此接口的类中,您有义务实现此方法。 对象引用bi是BaseInterface的类型,只能访问接口声明的方法。您不能使用Child类的bi(接口引用类型)方法。 如果你真的想要访问Child的方法,你必须进行演员表演。 我希望这会对你有所帮助。

enter image description here

interface BaseInterface{ void interMet(); } class BaseClass{ void baseClassMet(){ System.out.println("baseClassMet method in superclass"); } } public class Child extends BaseClass implements BaseInterface{ //overrided method void baseClassMet(){ System.out.println("baseClass method in extended class"); } //method of child void childMet(){ System.out.println("Child met"); } public void interMet() { System.out.println("Implemented method"); } public static void main(String[] args) { Child c = new Child(); c.baseClassMet();// prints "baseClass method in extended class" BaseClass b = new Child(); b.baseClassMet();// prints "baseClass method in extended class" b.childMet//can't access object method childMet() like this // Does not compile ((Child)b).childMet();//you can do it like this telling the compiler that //you are sure that b point to a Child object BaseClass b1 = new BaseClass(); b1.baseClassMet();//prints "baseClassMet method in superclass" BaseInterface bi = new Child();//assigning bi of type BaseInterface(interface) the object Child bi.interMet(); // this prints "Child met" }}

答案 3 :(得分:0)

引用的声明类型是您选择与Child实例交互的透视图,公开说明的透视图是子类的超类或接口。