java父类子类上下转型总结

来源:互联网 发布:制谱软件安卓版 编辑:程序博客网 时间:2024/05/21 19:41

接口的最主要的作用是达到统一访问,就是在创建对象的时候用接口创建,【接口名】 【对象名】=new 【实现接口的类】,这样你像用哪个类的对象就可以new哪个对象了,不需要改原来的代码,就和你的USB接口一样,插什么读什么,就是这个原理。就像你问的,都有个method1的方法,如果我用接口,我上面就可以one.method1();是吧?那样我new a();就是用a的方法,new b()就是用b的方法这样不方便吗?这个就叫统一访问,因为你实现这个接口的类的方法名相同,但是实现内容不同我用接口来定义对象不就可以做到统一访问了吗?接口主要针对多个类实现它来说的,要是只有一个类当然可以不用接口了.你这样想,我做一个USB接口,有个read()抽象方法,然后mp3类实现,U盘类实现,移动硬盘类实现,这样我用的时候用USB a=new 【类名】;这样a.read();要是我类名里写U盘,就读U盘,写mp3就读mp3,而这个名字可以从属性文件里读,你写哪个就用哪个了,呵呵。
接口是 java 多态的一种形式 interface A { public void print();} class B 和 class C 都实现了接口 a class D { public void d(A a){ a.print();} //这个方法要求传一个A对象的引用 ,这里只要是实现了接口A的对象都可以做为参数,会调用这个对象所实现的print()方法,有点像继承重载,但是接口更灵活,可以实现多个接口,继承只能继承一个父类. 
面向对象编程有三个特征,即封装、继承和多态。

向上转型可以像下面这条语句这么简单:

  Shape s =new Circle();

  这里,创建一个Circle对象,并把得到的引用立即赋值给S矇,这样做看似错误(将一种类型赋值给别一种类型);但实际上没有问题,因为通过继承,Circle就是一种Shape。因此,编译器认可这条语句,也就不会产生错误信息。

java 转型问题其实并不复杂,只要记住一句话:父类引用指向子类对象

转型例子:

public class A {
public void aMthod() { 
      System.out.println("A method"); 

}

public class B extends A {
public String name ;
void bMethod1() {  System.out.println("B method 1" + name );} 
void bMethod2() {  System.out.println("B method 2" + name ); } 
}

public static void main(String[] args) {
A a1 = new B(); // 向上转型 
          a1.aMthod();    // 调用父类aMthod(),a1遗失B类方法bMethod1()、bMethod2() 
         
         B bb = (B) a1; // 正常的,因为bb指向的是B子类,调用的也是B子类的方法。
          bb.name = "sun";
          bb.aMthod();   // 而这样的a1父类,必须是指向过子类,才可以向下转型。
          bb.bMethod1(); // sun可以打印

  // 当向下转型的时候,最后的子类bb可以像子类一样使用,如果没使用之前,子类bb打印的name是Null.主要是bb用了指向子类的父类,才可以向下转型,如果父类a1指向父类,就没办法转型了。
          A a2 = new A(); 
          B b2 = (B) a2; // 向下转型,编译无错误,运行时将出错 
          b2.aMthod(); 
          b2.bMethod1(); 
          b2.bMethod2(); 

}

其实黑体部分的向下转型代码后的注释已经提示你将发生运行时错误。为什么前一句向下转型代码可以,而后一句代码却出错?这是因为a1指向一个子类B的对象,所以子类B的实例对象b1当然也可以指向a1。而a2是一个父类对象,子类对象b2不能指向父类对象a2。那么如何避免在执行向下转型时发生运行时ClassCastException异常?使用5.7.7节学过的instanceof就可以了。我们修改一下C类的代码: A a2 = new A(); if (a2 instanceof B) { B b2 = (B) a2; b2.aMthod(); b2.bMethod1(); b2.bMethod2(); } 这样处理后,就不用担心类型转换时发生ClassCastException异常了。

1。父类引用指向子类对象,而子类引用不能指向父类对象。

2。把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转换。

      如:Father f1 = new Son();

3。把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转换。

   如:f1 就是一个指向子类对象的父类引用。把f1赋给子类引用s1即 Son s1 = (Son)f1;

           其中f1前面的(Son)必须加上,进行强制转换。

当在父类和子类中同时定义和赋值同名的成员变量name,并试图输出该变量的值时,父类引用输出的是父类的成员变量,也就是

父类的引用,按照道理只能调用父类的成员变量和函数,如果子类重写了父类的函数,就变成了多态,正好应验了父类引用指向子类对象的情况下多态的应用。

二.注意事项:

     (1)向上转型的对象的引用调用的方法是子类的。

     (2)但如果调用的方法父类中没有的话则会报错。(意思是只能调用子类中重载父类的方法)

     (3)父类的引用可以指向子类的对象,但是子类的引用不能指向父类的对象。

    子类的对象调用到的成员变量,是父类的成员变量(此时要想访问子类的成员变量,就要调用setter getter函数了[应该是覆写过的],情况跟多态一样)。

对于多态,可以总结它为:

    一、使用父类类型的引用指向子类的对象;该引用只能调用父类中定义的方法和变量;

    二、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)

    三、变量不能被重写(覆盖),”重写“的概念只针对方法。

-------------------------------- 华丽的分割线  深入理解java上下转型--------------------------------------

1. 引用在栈内存中存在对象的内存地址。真正的对象(通过 new Student()创建的)存放在堆内存里。

在这块堆内存区域内,存在的是子类的属性(包括自己特有的,以及通过super()构造方法中从父类获得的)

和方法(继承父类但没有覆盖的,以及覆盖父类的方法和自己特有的),尽管引用是声明为父类的引用,

但是它指向的子类的对象,在执行方法的时候,是通过引用指向的堆内存区域内执行的。也就是到底执行父类

方法还是子类方法是由对象决定的,跟引用没有直接关系。

2.
从对象的内存角度来理解试试.假设现在有一个父类Father,它里面的变量需要占用1M内存.有一个它的子类Son,它里面的变量需要占用0.5M内存.现在通过代码来看看内存的分配情况:Father f = new Father();//系统将分配1M内存.Son s = new Son();//系统将分配1.5M内存!因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数.由于s中包含了父类的实例,所以s可以调用父类的方法.Son s1 = s;//s1指向那1.5M的内存.Father f1 = (Father)s;//这时f1会指向那1.5M内存中的1M内存,即是说,f1只是指向了s中实例的父类实例对象,所以f1只能调用父类的方法(存储在1M内存中),而不能调用子类的方法(存储在0.5M内存中).Son s2 = (Son)f;//这句代码运行时会报ClassCastException.因为f中只有1M内存,而子类的引用都必须要有1.5M的内存,所以无法转换.Son s3 = (Son)f1;//这句可以通过运行,这时s3指向那1.5M的内存.由于f1是由s转换过来的,所以它是有1.5M的内存的,只是它指向的只有1M内存.
 

    -------------------------------- 华丽的分割线  多态总结--------------------------------------

对于多态,可以总结它为:       

    一、使用父类类型的引用指向子类的对象;

    二、该引用只能调用父类中定义的方法和变量;

    三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)

    四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。

多态的3个必要条件:

    1.继承   2.重写   3.父类引用指向子类对象。




0 0
原创粉丝点击