C#中的上转型对象问题和多态问题。
发布网友
发布时间:2024-10-03 15:03
我来回答
共2个回答
热心网友
时间:2024-10-04 11:30
我是学java的,你可以参照的理解
向上转型
我们在现实中常常这样说:这个人会唱歌。在这里,我们并不关心这个人是黑人还是白人,是*还是小孩,也就是说我们更倾向于使用抽象概念“人”。再例如,麻雀是鸟类的一种(鸟类的子类),而鸟类则是动物中的一种(动物的子类)。我们现实中也经常这样说:麻雀是鸟。这两种说法实际上就是所谓的向上转型,通俗地说就是子类转型成父类。这也符合Java提倡的面向抽象编程思想。来看下面的代码:
package a.b;
public class A {
public void a1() {
System.out.println("Superclass");
}
}
A的子类B:
package a.b;
public class B extends A {
public void a1() {
System.out.println("Childrenclass"); //覆盖父类方法
}
public void b1(){} //B类定义了自己的新方法
}
C类:
package a.b;
public class C {
public static void main(String[] args) {
A a = new B(); //向上转型
a.a1();
}
}
如果运行C,输出的是Superclass 还是Childrenclass?不是你原来预期的Superclass,而是Childrenclass。这是因为a实际上指向的是一个子类对象。当然,你不用担心,Java虚拟机会自动准确地识别出究竟该调用哪个具体的方法。不过,由于向上转型,a对象会遗失和父类不同的方法,例如b1()。有人可能会提出疑问:这不是多此一举吗?我们完全可以这样写:
B a = new B();
a.a1();
确实如此!但这样就丧失了面向抽象的编程特色,降低了可扩展性。其实,不仅仅如此,向上转型还可以减轻编程工作量。来看下面的显示器类Monitor:
package a.b;
public class Monitor{
public void displayText() {}
public void displayGraphics() {}
}
液晶显示器类LCDMonitor是Monitor的子类:
package a.b;
public class LCDMonitor extends Monitor {
public void displayText() {
System.out.println("LCD display text");
}
public void displayGraphics() {
System.out.println("LCD display graphics");
}
}
阴极射线管显示器类CRTMonitor自然也是Monitor的子类:
package a.b;
public class CRTMonitor extends Monitor {
public void displayText() {
System.out.println("CRT display text");
}
public void displayGraphics() {
System.out.println("CRT display graphics");
}
}
等离子显示器PlasmaMonitor也是Monitor的子类:
package a.b;
public class PlasmaMonitor extends Monitor {
public void displayText() {
System.out.println("Plasma display text");
}
public void displayGraphics() {
System.out.println("Plasma display graphics");
}
}
现在有一个MyMonitor类。假设没有向上转型,MyMonitor类代码如下:
package a.b;
public class MyMonitor {
public static void main(String[] args) {
run(new LCDMonitor());
run(new CRTMonitor());
run(new PlasmaMonitor());
}
public static void run(LCDMonitor monitor) {
monitor.displayText();
monitor.displayGraphics();
}
public static void run(CRTMonitor monitor) {
monitor.displayText();
monitor.displayGraphics();
}
public static void run(PlasmaMonitor monitor) {
monitor.displayText();
monitor.displayGraphics();
}
}
可能你已经意识到上述代码有很多重复代码,而且也不易维护。有了向上转型,代码可以更为简洁:
package a.b;
public class MyMonitor {
public static void main(String[] args) {
run(new LCDMonitor());//向上转型
run(new CRTMonitor());//向上转型
run(new PlasmaMonitor());//向上转型
}
public static void run(Monitor monitor) { //父类实例作为参数
monitor.displayText();
monitor.displayGraphics();
}
}
我们也可以采用接口的方式,例如:
package a.b;
public interface Monitor {
abstract void displayText();
abstract void displayGraphics();
}
将液晶显示器类LCDMonitor稍作修改:
package a.b;
public class LCDMonitor implements Monitor {
public void displayText() {
System.out.println("LCD display text");
}
public void displayGraphics() {
System.out.println("LCD display graphics");
}
}
CRTMonitor、PlasmaMonitor类的修改方法与LCDMonitor类似,而MyMonitor可以不不作任何修改。
可以看出,向上转型体现了类的多态性,增强了程序的简洁性。
向下转型
子类转型成父类是向上转型,反过来说,父类转型成子类就是向下转型。但是,向下转型可能会带来一些问题:我们可以说麻雀是鸟,但不能说鸟就是麻雀。来看下面的例子:
A类:
package a.b;
public class A {
void aMthod() {
System.out.println("A method");
}
}
A的子类B:
package a.b;
public class B extends A {
void bMethod1() {
System.out.println("B method 1");
}
void bMethod2() {
System.out.println("B method 2");
}
}
C类:
package a.b;
public class C {
public static void main(String[] args) {
A a1 = new B(); // 向上转型
a1.aMthod();// 调用父类aMthod(),a1遗失B类方法bMethod1()、bMethod2()
B b1 = (B) a1; // 向下转型,编译无错误,运行时无错误
b1.aMthod();// 调用父类A方法
b1.bMethod1(); // 调用B类方法
b1.bMethod2(); // 调用B类方法
A a2 = new A();
B b2 = (B) a2; // 向下转型,编译无错误,运行时将出错
b2.aMthod();
b2.bMethod1();
b2.bMethod2();
}
}
从上面的代码我们可以得出这样一个结论:向下转型需要使用强制转换。运行C程序,控制台将输出:
Exception in thread "main" java.lang.ClassCastException:a.b.A cannot be cast to a.b.B at
a.b.C.main(C.java:14)
A method
A method
B method 1
B method 2
其实黑体部分的向下转型代码后的注释已经提示你将发生运行时错误。为什么前一句向下转型代码可以,而后一句代码却出错?这是因为a1指向一个子类B的对象,所以子类B的实例对象b1当然也可以指向a1。而a2是一个父类对象,子类对象b2不能指向父类对象a2。那么如何避免在执行向下转型时发生运行时ClassCastException异常?使用以前学过的instanceof就可以了。我们修改一下C类的代码:
A a2 = new A();
if (a2 instanceof B) {
B b2 = (B) a2;
b2.aMthod();
b2.bMethod1();
b2.bMethod2();
}
热心网友
时间:2024-10-04 11:30
我也是学java的,我简单说一下,上转型就是通过实例化实现接口或者继承抽象类来实例化接口或者抽象类如: 接口名 对象名=new 继承接口的类,抽象类一样
这只是最简单的上转型,多态就是继承和方法重写啦,只能说这些,详细的不只是这些,你可以通过这些去了解,
之前帮你解决问题的那个人回答很精辟,但是理解还是基础点的东西好.上转型是为了使一个对象可以调用出其他同类型的东西.
回答很通俗,请谅解
C#中的上转型对象问题和多态问题。
public static void main(String[] args) { A a = new B(); //向上转型 a.a1();} } 如果运行C,输出的是Superclass 还是Childrenclass?不是你原来预期的Superclass,而是Childrenclass。这是因为a实际上指向的是一个子类对象。当然,你不用担心,Java虚拟机会自动准确地识别出究竟该调用哪个具...
C++ 里的向上转型啥意思??
向上转型是对A的对象的方法的扩充。向上转型这面向对象(c# Java AS3.0)编程(oop)中多态的方面,分为向上转型和向下转型。假定父类为 动物,子类为狗,父类有一个方法发声(),狗继承并覆盖了一个发声方法。在子类重写该方法 则(以下过程c#实现):动物 a=new 狗();//这就为向上转型a....
JAVA中关于继承,上转型下转型的问题。
一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法这句话是有问题的。1。该变量可以访问子类的方法,不过方法必须是子类重写的父类的方法,并且编译的时候调用的是父类的方法,而在运行的时候就是访问的子类重写的方法。一句话:因为多态。2...
c++中使用new后的强制类型转换问题
使用上转型对象需要注意,无法使用派生类独有而基类中没有的成员,另外,如果派生类有重写基类的虚函数,调用上转型对象的成员函数时,将执行派生类重写的虚函数中的内容而不执行基类中的对应成员函数的内容。这是多态的一种实现方式。上转型对象中,用作引用的基类可以是抽象类,还可以是虚基类(相当于Ja...
java中对象的向上向下转型在开发中用于实现什么功能
失:上转型对象丧失了对子类新增成员变量或新增的方法的操作和使用。2与向上转型相反,即是把父类对象转为子类对象:作用也与上转相反。java 转型问题其实并不复杂,只要记住一句话:父类引用指向子类对象。子类和父类中定义同名的变量时,仅仅是隐藏了,变量没有多态性;而对于覆盖的方法,Java表现出...
为何使用hashmap的hasnext,add,net方法的时候需要向上转型???
向上转换本身不是必须,但很多时候就是为了提醒"不要假设我们必须使用 HashMap",好让后面的代码都忘记它是一个 HashMap,当我们调用其它方法时应该这样,不要作出不必要的假设能让你程序更稳定,修改一个小细节也不容易出错,因为你只使用了接口上声明的方法,不假设某些不应该你知道的细节,因为这些...
java中的向上转型和向下转型问题。为什么一步到位的向下转型会报错,而...
所以转型没有问题 情况2: new AA() 中可能不包含BB类的全部变量和方法,强制转换无法实现 思考方法:JAVA中的变量名看成数据指针,new 是在内存中实际的创造一个实例。当创造了一个子类的实例时,指针类型是父类或子类都没有关系。但父类的实例不可能用子类的指针来表达。
什么是多态?
当通过父类引用调用子类的方法时,这种行为被称为动态绑定,它发生在运行时,而非编译时。这种“向上转型”(upcasting)的机制使得我们可以只编写针对基类的代码,而这些代码能够适用于整个类家族,这就是多态性的直观体现。总的来说,多态是面向对象编程中一个强大且灵活的工具,它促进了代码的复用和扩展...
JAVA里什么是上转型对象?
public void drink(){System.out.println("YongMan");}} } public class Test{ public static void main(String arge[]){ Human e2=new YongMan();e2.drink();} } 以上面这个程序为例子 Human e2=new YongMan();这句其实是指父类对象e2是子类YongMan对象的上转型对象 上转型对象不能操作...
java中关于父类引用指向子类对象,多态性的问题~虚心求教
但是子类炒菜方法与parent完全不同(儿子喜欢另一种炒菜方法),那么在程序中调用p.炒菜方法时,就会调用子类的炒菜方法。所以多态实现的是:通过父类或接口调用子类或实现类里的重写方法或者实现方法,除非继承的子类没有重写父类任何方法,否则调用的都是子类里边重写的方法 ...