java向上转型神解析
向上转型
经典案例
public class Animal {
public void eat(){
System.out.println("animal eatting...");
}
}
public class Cat extends Animal{
public void eat(){
System.out.println("我吃鱼");
}
}
public class Dog extends Animal{
public void eat(){
System.out.println("我吃骨头");
}
public void run(){
System.out.println("我会跑");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Cat(); //向上转型
animal.eat();
animal = new Dog();
animal.eat();
}
}
//结果:
//我吃鱼
//我吃骨头
当父类对象引用变量引用子类对象时,被引用对象的类型决定了调用谁的成员方法,引用变量类型决定可调用的方法。Animal是引用变量类型,它决定哪些方法可以调用;eat()方法可以调用,而cat是被引用对象的类型,它决定了调用谁的方法:调用cat的方法。
向上转型
- 子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口。
Animal animal = new Cat();将子类对象Cat转化为父类对象Animal。这个时候animal这个引用调用的方法是子类方法。
向上转型应注意的问题
向上转型时,子类单独定义的方法会丢失。比如上面Dog类中定义的run方法,当animal引用指向Dog类实例时是访问不到run方法的,
animal.run()会报错。子类引用不能指向父类对象。
Cat c = (Cat)new Animal()这样是不行的。Fu f=new Zi();
1、将子类对象赋值给父类对象,父类对象就成了子类的上转型对象,但是这只能访问从父类继承的方法和变量或者重写的方法。
2、只能让上转型对象调用(访问)子类中与父类有关的成员,子类中自己后定义的成员不能被调用(变量或方法)
向上转型的好处
- 减少重复代码,使代码变得简洁。
- 提高系统扩展性。
举个例子:比如我现在有很多种类的动物,要喂它们吃东西。如果不用向上转型,那我需要这样写:
public void eat(Cat c){
c.eat();
}
public void eat(Dog d){
d.eat();
}
//......
eat(new Cat());
eat(new Cat());
eat(new Dog());
//......
一种动物写一个方法,如果我有一万种动物,我就要写一万个方法,写完大概猴年马月都过了好几个了吧。好吧,你很厉害,你耐着性子写完了,以为可以放松一会了,突然又来了一种新的动物,你是不是又要单独为它写一个eat方法?开心了么?
那如果我使用向上转型呢?我只需要这样写:
public void eat(Animal a){
a.eat();
}
eat(new Cat());
eat(new Cat());
eat(new Dog());
//.....
恩,搞定了。代码是不是简洁了许多?而且这个时候,如果我又有一种新的动物加进来,我只需要实现它自己的类,让他继承Animal就可以了,而不需要为它单独写一个eat方法。是不是提高了扩展性?
class Fuc{
public int num=100;
public void show(){
System.out.println("show Fuc");
}
}
class Zic extends Fuc{
public int num=1000;
public int num2=200;
@Override
public void show() {
System.out.println("show Zic");
}
}
public class DuoTai {
public static void main(String[] args) {
Fuc f=new Zic();
System.out.println(f.num);
//System.out.println(f.num2); 编译错误
f.show();
}
}
编译器在编译阶段会先看父类,编译器通过声明对象的类型(即引用本身的类型)在方法区中该类型的方法表中查找匹配的方法。所以起初父类中没有num2变量,你用父类的引用去访问子类的变量编译不会通过,子类可以访问父类,但是父类不能访问子类,因为子类继承了父类。通俗点说就是儿子可以访问父亲,但是你父亲不能访问儿子。
静态方法的调用
class A {
public static void show(){
System.out.println("hhhh");
}
}
class B extends A {
public static void show(){
System.out.println("你哈");
}
}
public class C{
public static void main(String[] args) {
A b=new B();
b.show();
}
}
静态方法不具有多态性,因为
静态和类相关,和对象实例无关,静态方法可以继承和重写,但重写只是形式上的(算不上重写),父类方法并没有被覆盖掉。同名将隐藏。静态方法是被隐藏而不是被覆盖,所以上转型变量调用这个静态方法时,调用的是子类中继承的并且被隐藏的static方法,深层次去理解就是静态方法属于静态绑定,在编译过程中,方法与引用变量类型绑定,编译器看的是父类,所以运行时以声明类型为准,上转型变量调用的是继承且被隐藏的static方法。
java向上转型神解析的更多相关文章
- Java向上转型和向下转型(附具体样例)
Java向上转型和向下转型(附具体样例) 熬夜整理的关于Java向上和向下转型的样例,很的通俗易懂哦~~~~ 一 ...
- (原)java 向上转型中,任何域的访问操作都是由编译器解析,不是多态
最近在向java发力,学习学习了下.看到了多态这一节,书中有个比较好的例子,所以就准备写下来,记录下来: package dynamic_binding01; public class dynamic ...
- java 向上转型 向下转型
//父类 四边形 class Quadrangle{ public static void draw (Quadrangle q){ } } //子类 public class Parallelog ...
- Java向上转型的意义
比如我这个程序 public class Testjava{ public static void main(String args[]) { fun(new Student()); fun(new ...
- java 向上转型与向下转型
转型是在继承的基础上而言的,继承是面向对象语言中,代码复用的一种机制,通过继承,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展. 向上转型:子类引用的对象 ...
- java向上转型和向下转型1
在java继承体系中,认为父类(超类)在上层,子类在下层(派生类) ,向上转型就是把子类对象转成父类对象. public class Father { public void eat(){ Syste ...
- java 向上转型和向下转型
学习向上转型和向下转型怎么用没多难,但是为什么那样用,我搞了很多次没弄明白.没弄明白的原因是平时学习时之看例子,而例子一般都比较简单,没有对象之间的调用,一般就是一个对象调用自己的方法. 首先看下怎么 ...
- java向上转型和向下转型
转型是在继承的基础上而言的,继承是面向对象语言中,代码复用的一种机制,通过继承,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展. 向上转型:子类引用的对象 ...
- java向上转型的问题
import java.util.Arrays;import java.util.HashSet;import java.util.Set;class A{ private String s1 = & ...
随机推荐
- Java并发--基础知识
一.为什么要用到并发 充分利用多核CPU的计算能力 方便进行业务拆分,提升应用性能 二.并发编程有哪些缺点 频繁的上下文切换 时间片是CPU分配给各个线程的时间,因为时间非常短,所以CPU不断通过切换 ...
- C#LeetCode刷题之#581-最短无序连续子数组( Shortest Unsorted Continuous Subarray)
问题 给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 输入: [2, 6, 4, 8, 10, ...
- Vue <script></script>区域使用filter过滤器
Vue中过滤器(filter)的功能高度提取,便于使用,前端小伙伴们使用的频率很高.但大多数都是在模板区域来使用. 如果要在脚本区域, 也就是来使用已经定义好过滤器功能,该如何去做呢? 难道需要在ut ...
- QUIC协议详解之Initial包的处理
从服务器发起请求开始追踪,细说数据包在 QUIC 协议中经历的每一步.大量实例代码展示,简明易懂了解 QUIC. 前言 本文介绍了在 QUIC 服务器在收到 QUIC 客户端发起的第一个 UDP 请求 ...
- DB2数据库错误代码大全
SQLCode SQLState 状态说明 000 00000 SQL语句成功完成 01xxx XXX SQL语句成功完成,但是有警告 +012 01545 未限定的列名被解释为一个有相互关系的引用 ...
- 怎么对比两个excel文档的数据差异
百度经验: https://jingyan.baidu.com/article/6181c3e0877c7a152ef15304.html
- .Net Core中的诊断日志DiagnosticSource讲解
前言 近期由于需要进行分布式链路跟踪系统的技术选型,所以一直在研究链路跟踪相关的框架.作为能在.Net Core中使用的APM,SkyWalking自然成为了首选.SkyAPM-dotnet是 ...
- golang IPv6 转 十进制
IPv4 互换: package main import ( "fmt" "math/big" "net" ) func InetNtoA( ...
- 对于CSS里面我之前不太清楚的伪类,我做一些总结
格式: 标签 + : + 参数 +{ 可填背景颜色,字体颜色,鼠标样式,加粗等 } a:hover{ color:#f40;} :link表示鼠标点击之前的样式 :hover表示鼠标放上去的样式 :a ...
- 第5篇scrum冲刺(5.25)
一.站立会议 1.照片 2.工作安排 成员 昨天已完成的工作 今天的工作安排 困难 陈芝敏 线下模块(还剩下获取词的数据库) 研究云开发,更新了登录模块,把用户的信息传入数据库了 起初在云函数 ...