java父类引用指向子类对象好处_java子类调用父类属性

java父类引用指向子类对象好处_java子类调用父类属性1.什么是多态?方法的重写、重载与动态连接构成多态性Java之所以引入多态的概念,原因之一就它在类的继承上的问题和C++不同,后者允许多继承,这确实给其带来了非常强大的功能,但是复杂的继承关系也给C++开发者带来了更大的麻烦,为了规避风险,Java只允许单继承,势必在功能上有很大的限制,所以,Java引入多态性的概念以弥补这点不足,此外,抽象类和接口也是解决单继承规定限制的重要手段.同时,…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

1.什么是多态?

方法的重写、重载与动态连接构成多态性

Java之所以引入多态的概念,原因之一就它在类的继承上的问题和C++不同,后者允许多继承,这确实给其带来了非常强大的功能,但是复杂的继承关系也给C++开发者带来了更大的麻烦,为了规避风险,Java只允许单继承,势必在功能上有很大的限制,所以,Java引入多态性的概念以弥补这点不足,此外,抽象类和接口也是解决单继承规定限制的重要手段.同时,多态也是面向对象编程的精髓所在.

2.多态的体现

1 接口 和 实现接口并覆盖接口中同一方法的几不同的类体现的

2 父类 和 继承父类并覆盖父类中同一方法的几个不同子类实现的.

子类覆盖父类实现多态:

    如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性,不过,抽象类的子类必须覆盖实现超类中的所有的抽象方法,否则子类必须被abstract修饰符修饰,当然也就不能被实例化了

重写父类方法:

//父类
public class Father{
//父类有一个打孩子方法
	public void hitChild(){
	}
}
//子类1
public class Son1 extends Father{
//重写父类打孩子方法
	public void hitChild(){
		System.out.println("为什么打我?我做错什么了!");
	}
}
//子类2
public class Son2 extends Father{
//重写父类打孩子方法
	public void hitChild(){
		System.out.println("我知道错了,别打了!");
	}
}
//子类3
public class Son3 extends Father{
//重写父类打孩子方法
	public void hitChild(){
		System.out.println("我跑,你打不着!");
	}
}

//测试类
public class Test{
	public static void main(String args[]){
		Father father;
	
		father = new Son1();
		father.hitChild();
	
		father = new Son2();
		father.hitChild();
	
		father = new Son3();
		father.hitChild();
	}
}
//重写父类打孩子方法
	public void hitChild(){
		System.out.println("我跑,你打不着!");
	}
}

//测试类
public class Test{
	public static void main(String args[]){
		Father father;
	
		father = new Son1();
		father.hitChild();
	
		father = new Son2();
		father.hitChild();
	
		father = new Son3();
		father.hitChild();
	}
}

Jetbrains全家桶1年46,售后保障稳定

 

   Java里没有多继承,一个类之能有一个父类。而继承的表现就是多态。一个父类可以有多个子类,而在子类里可以重写父类的方法(例如方法print()),这样每个子类里重写的代码不一样,自然表现形式就不一样。这样用父类的变量去引用不同的子类,在调用这个相同的方法print()的时候得到的结果和表现形式就不一样了,这就是多态,相同的消息(也就是调用相同的方法)会有不同的结果

 

都调用了相同的方法,出现了不同的结果!这就是多态的表现!

 

3.如何理解向上转型?

我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类。我可以通过

Cat c = new Cat();

实例化一个Cat对象,这个不难理解。但当我这样定义时:

Animal a = new Cat();

这样代表什么意思呢?

很简单,它表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象。由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的。那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特:

    定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。

所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;

 

对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。

来我们举个栗子:

class Father {
	public void func1(){
		func2();
	} 
	public void func2(){
		System.out.println("AAA");
	}
}

class Child extends Father{
	
	public void func1(int i){
		System.out.println("BBB");
		} 
	
	public void func2(){
		System.out.println("CCC");
		}
	
}


public class Test {
	public static void main(String[] args) {
		
		Father child = new Child();
		child.func1();//打印结果将会是什么?
  }
}

上面的程序是个很典型的多态的例子。子类Child继承了父类Father,并重载了父类的func1()方法,重写了父类的func2()方法。重载后的func1(int i)和func1()不再是同一个方法,由于父类中没有func1(int i),那么,父类类型的引用child就不能调用func1(int i)方法。而子类重写了func2()方法,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2()。

  经过上面的分析我们可以知道打印的结果是什么呢? 很显然,应该是”CCC”

4.对于多态总结一下

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

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

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

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

在现实生活中的体现:

      自己用自己的,儿子有父亲一样的,就用儿子的。省点钱是点。儿子独有的,父亲不会用,所以不能用

5.站在内存分配的角度分析

    1.从对象的内存角度来理解. 

假设现在有一个父类Father,它里面的变量需要占用1M内存.有一个它的子类Son,里面的变量需要占用0.5M内      存.   
    2.现在通过代码来看看内存的分配情况:

    f = new Father();//系统将分配1M内存.
    Son s = new Son();//系统将分配1.5M内存
//系统将分配1M内存.
    Son s = new Son();//系统将分配1.5M内存

     因为子类中有一个隐藏的引用super会指向父类实例,所以在实例    化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数.由于s中包含了父类的实例,所以s可以调用   父类的方法.
    3.

  

    Son s1 = s;//s1指向那1.5M的内存.
    Father f1 = (Father)s;//这时f1会指向那1.5M内存中的1M内存//s1指向那1.5M的内存.
    Father f1 = (Father)s;//这时f1会指向那1.5M内存中的1M内存

    即是说,f1只是指向了s中实例的父类实例对象,所以f1只能调用父类的方法(存储在1M内存中),而不能调用子类的方法(存储在0.5M内存中).
   

Son s2 = (Son)f;//这句代码运行时会报ClassCastException.//这句代码运行时会报ClassCastException.

  因为f中只有1M内存,而子类的引用都必须要有1.5M的内存,所以无法转换.

Son s3 = (Son)f1;//这句可以通过运行,这时s3指向那1.5M的内存.//这句可以通过运行,这时s3指向那1.5M的内存.

  由于f1是由s转换过来的,所以它是有1.5M的内存的,只是它指向的只有1M内存.

  所以可以实现强转…
    4.static   顾名思义,就是静态的,他是方法的,他属于这个类,由于是类的方法,他可以直接引用类名来引用方法,也可以通过类的对象来引用这个方法,他既不能被子类覆盖,也不能被子类继承。简单的说,他是在编译的时候就和类帮定在一起了,不能被运行时动态加载。

   对子类与父类的static问题
    ——没覆盖也没继承,子类存有指向父类的引用

    对于private
    ——该方法或属性只能在该类内使用

 

 

 

 

 

 

 

 

 

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/203204.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • python产生随机数的方法_产生随机数的函数

    python产生随机数的方法_产生随机数的函数Python产生随机数:一.Python自带的random库1.参生n–m范围内的一个随机数:random.randint(n,m)2.产生0到1之间的浮点数:random.random()3.产生n—m之间的浮点数:random.uniform(1.1,5.4)4.产生从n—m间隔为k的整数:random.randrange(n,m,k)5.从序列中随机选取一个元素:random.choice([1,2,3,4,5,6,7

  • MFS学习总结

    MFS学习总结公司使用moosefs做图片存储,最近学习了一下,在此小小总结一下,主要分以下几部分:MFS概述、特性和新版改进MFS工作原理和设计架构MFS的安装、部署、配置MFS的高级特性MFS的性能测试MFS

  • js数组转对象_js数组去重的四种方法

    js数组转对象_js数组去重的四种方法js数组转对象1.jsvarlist={};vararr=["123","456","789"];for(varkeyinarr){list[key]=arr[key];}console.log(list);效果:

  • hdu 4964 Emmet()模拟

    hdu 4964 Emmet()模拟

  • 30 个重要数据结构和算法完整介绍建议保存

    30 个重要数据结构和算法完整介绍建议保存数据结构和算法(DSA)通常被认为是一个令人生畏的话题——一种常见的误解。它们是技术领域最具创新性概念的基础,对于工作/实习申请者和有经验的程序员的职业发展都至关重要。话虽如此,我决定在CSDN新星计划挑战期间将我所了解的数据结构和算法集中起来。本文旨在使DSA看起来不像人们认为的那样令人生畏。它包括15个最有用的数据结构和15个最重要的算法,可以帮助您在学习中和面试中取得好成绩并提高您的编程竞争力。后面等我还会继续对这些数据结构和算法进行进一步详细地研究讲解。

  • kafka应用场景包括_rabbitmq使用场景

    kafka应用场景包括_rabbitmq使用场景Kafka核心概念与应用场景

    2022年10月14日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号