资讯专栏INFORMATION COLUMN

Java笔记 - 重写/重载,向上转型/向下转型

qqlcbb / 1055人阅读

摘要:所以静态方法不能被覆盖。虽然就算你重写静态方法,编译器也不会报错。也就是说,如果你试图重写静态方法,不会阻止你这么做,但你却得不到预期的结果重写仅对非静态方法有用。我们应该直接使用类名来访问静态方法,而不要使用对象引用来访问。

重写/重载

重写指的是根据运行时对象的类型来决定调用哪个方法,而不是根据编译时的类型。所以静态方法不能被覆盖

(如果从重写方法会有什么特点来看,我们是不能重写静态方法的。虽然就算你重写静态方法,编译器也不会报错。也就是说,如果你试图重写静态方法,Java 不会阻止你这么做,但你却得不到预期的结果(重写仅对非静态方法有用)。重写指的是根据运行时对象的类型来决定调用哪个方法,而不是根据编译时的类型。让我们猜一猜为什么静态方法是比较特殊的?因为它们是类的方法,所以它们在编译阶段就使用编译出来的类型进行绑定了。使用对象引用来访问静态方法只是 Java 设计者给程序员的自由。我们应该直接使用类名来访问静态方法,而不要使用对象引用来访问。)

向上转型/向下转型

assume 两个类 Base 类 和 Agg 类,Agg 继承与 Base .
and 一个原则:父类引用指向子类对象,子类引用不能指向父类对象(不安全)。

1 向上转型
javaBase f1 = new Agg (); 父类引用指向子类对象

左边叫 生成一个父类引用Father f1
右边叫 生成一个子类对象new Son() f1 引用指向了内存堆中Son对象。
把子类对象直接赋给父类的引用叫向上转型,向上转型不用强制转换。向上转型就是父类引用指向子类对象,这里谁指向谁记着不方便,一个简单的记忆方法是 A a = new B(); 可以想象一个箭头 A a => new B(); namely, A 指向 B.

javaclass Base{
    public String getField(){
        String name = "Base";
            return name;
    }
}
class Agg extends Base{
    public String getField(){
        String name = "Agg";
            return name;
    }
}
javapublic class test {
    public static void main(String[] args) {
        Base a = new Agg();
        System.out.println(""+a.getField());
    }
}

output: Agg
动态绑定,覆盖了父类的函数
当我们调用a的方法的时候,我们会首先看看a对应的类有没有这个方法, 如果有并且被子类覆盖,这边就会调用子类的方法。

javaclass Base{}
class Agg extends Base{
    public String getField(){
        String name = "Agg";
        return name;
    }
}
public class test {
    public static void main(String[] args) {
        Base a = new Agg();
        System.out.println(""+ ((Agg)a).getField());
    }
}

output: Agg.
如果没有,编译器就认为Base没有这个函数,直接调用就会报错 (从这里也能看出向上转型会丢掉子类的一些信息)。
这时候吧a转换成Agg类型的对象,编译器就认为a是一个Agg 类型。可以调用Agg类的函数。

javaclass Base{
    public String getField(){
        String name = "Base";
        return name;
    }
}
class Agg extends Base{
    public String getField(){
        String name = "Agg";
            return name;
    }
}
public class test {
    public static void main(String[] args) {
        Agg b = new Agg();
        Base a =  (Base)b; 向上转型的另一个写法
        System.out.println(""+a.getField());
    }
}

output: Agg
这道题是向上转型的另一个写法.

java
class Base{ public static String getField(){ String name = "Base"; return name; } } class Agg extends Base{ public static String getField(){ String name = "Agg"; return name; } } public class test { public static void main(String[] args) { Agg a = new Agg(); Base b = new Agg(); System.out.println(""+a.getField()); System.out.println(""+b.getField()); } }

output : Agg Base
静态函数不能覆盖

2 向下转型
javaSon s1 = (Son)f1;

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

javaFather f2 = new Father();
Son s1 = (Son)f2; //编译出错,子类引用不能指向父类对象

javaclass Base{
    public String getField(){
        String name = "Base";
            return name;
    }
}
class Agg extends Base{
    public String getField(){
        String name = "Agg";
            return name;
    }
}
public class test {
    public static void main(String[] args) {
        Base a = new Base();
        Agg b = (Agg)a;  不会编译通过,这样向下转型不可以,不安全。
        System.out.println(""+b.getField());
    }
}

向下转型:当比较对象的时候,向下转型是很有用的。
那应该如何安全的向下转型?
先向上 - 再向下

javaBase b = new Agg(); 先向上
Agg a= (Agg)b; 再向下

再贴一个向下转型实际应用场景的代码,比较对象:

javapublic class Person
{
  private String name;
  private int age;

  public boolean equals(Object anObject)
  {
     if (anObject == null)
         return false;

     /* The object being passed in is checked
         to see it"s class type which is then compared
         to the class type of the current class.  If they
         are not equal then it returns false
     */

     else if (getClass( ) != anObject.getClass())
         return false;

     else
     {
        /* 
         this is a downcast since the Object class
         is always at the very top of the inheritance tree
         and all classes derive either directly or indirectly 
         from Object:
        */
        Person aPerson = (Person) anObject;
        return ( name.equals(aPerson.name) 
                && (age == aPerson.age));
     }
  }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64269.html

相关文章

  • 1、接口 2、多态

    摘要:接口的概念接口的概念接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的类。多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态。 01接口的概念 * A:接口的概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的类。 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成。这样将功能的定...

    Magicer 评论0 收藏0
  • 9. java 多态

    摘要:概念所谓多态,就是指一个引用变量类型在不同的情况下的多种状态。需进行强制转换有风险,最好使用进行判断。继承在多态中必须存在有继承关系的子类和父类。在中有两种形式可以实现多态继承和接口。 概念 所谓多态,就是指一个引用变量(类型)在不同的情况下的多种状态。也可以理解为,多态是指通过指向父类的指针,来调用在不同子类中实现的方法。多态性是对象多种表现形式的体现 多态性严格来说有两种描述形式:...

    wanglu1209 评论0 收藏0
  • 面向对象接口多态

    摘要:多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态。具体格式如下父类引用指向子类对象就是多态的定义格式。多态的转型分为向上转型与向下转型两种向上转型当有子类对象赋值给一个父类引用时,便是向上转型,多态本身就是向上转型的过程。 第3天 面向对象 今日内容介绍 接口 多态 笔记本案例今日学习目标 写出定义接口的格式 写出实现接口的格式...

    wangdai 评论0 收藏0
  • 向上转型读书笔记

    摘要:把这种对某个对象的引用视为对其基类的引用的做法被称作向上转型。或者继承或者重写了的问题从子类向上转型到父类,可能会缩小接口。因为向上转型之后使用引用进行访问,只能访问父类定义的接口,而不能访问自己定义的新接口。 preliminary 最近在读Thinking in Java这篇是一个基本此书的整理。 什么是向上转型upcast? 对象既可以作为它本身的类型使用,也可以作为它的基类...

    RdouTyping 评论0 收藏0
  • Java编程思想》笔记8.多态

    摘要:多态的作用是消除类型之间的耦合关系。编写构造器准则用尽可能简单的方法使对象进入正常状态,如果可以的话,避免调用其他方法。 点击进入我的博客 在面向对象的程序设计语言中,多态是继数据抽象(封装)和继承之后的第三种基本特征。多态通过分离做什么和怎么做,从另一角度将接口和实现分离开来。多态的作用是消除类型之间的耦合关系。 8.1 再论向上转型 对象既可以作为它自己的本类使用,也可以作为它的...

    chinafgj 评论0 收藏0

发表评论

0条评论

qqlcbb

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<