Java继承后访问成员的特点
继承后的特点——成员变量
对象访问成员变量时,会先在子类中查找有没有定义对应的变量,若子类中存在就会就近使用子类中的变量,若子类中没有定义就会沿着继承关系往上找有没有定义相应的变量,若父类中也没有则编译不通过。代码示例:
class Fu {
// Fu类中的成员变量。
int num = 5;
int num2 = 7;
}
class Zi extends Fu {
// Zi类中的成员变量
int num = 6;
public void show() {
// 访问父类中的num2
System.out.println("num2=" + num2);
// 访问子类中的num
System.out.println("num=" + num);
}
}
public class ExtendsDemo0 {
public static void main(String[] args) {
// 创建子类对象
Zi z = new Zi();
// 调用子类中的show方法
z.show();
}
}
演示结果:
num2=7
num=6
子父类中出现了同名的成员变量时,在子类中访问父类中非私有成员变量,需要使用 super 关键字,用法类似于 this 。
使用格式:
super.父类成员变量名
代码如下:
class Zi extends Fu {
// Zi类中的成员变量
int num = 6;
public void show() {
//访问父类中的num
System.out.println("Fu num2=" + num2);
//访问父类中的num
System.out.println("Fu num=" + super.num);
}
}
演示结果:
Fu num = 7
Zi num = 5
Fu 类中的私有成员变量,子类是不能直接访问的。编码时,遵循封装的原则,使用private修饰成员变量,可以在父类中提供公共的getXxx方法和setXxx方法来访问。
super和this
父类空间优先于子类对象产生
在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员。代码体现在子类的构造方法调用时,一定先调用父类的构造方法。理解图解如下:

super和this的含义
super :代表父类的存储空间标识(可以理解为父类的引用)。
this :代表当前对象的引用(谁调用就代表谁)。
super和this的用法
this.成员变量 -- 本类的
super.成员变量 -- 父类的
this.成员方法名() -- 本类的
super.成员方法名() -- 父类的
代码示例:
class Animal {
public void eat() {
System.out.println("animal : eat");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("cat : eat");
}
public void eatTest() {
this.eat(); // this 调用本类的方法
super.eat(); // super 调用父类的方法
}
}
public class ExtendsDemo08 {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Cat c = new Cat();
c.eatTest();
}
}
输出结果为:
animal : eat
cat : eat
animal : eat
注意:
通过super引用属性、方法、构造器时,都要求该成员是可见的,即该成员的修饰符不能是private的,跨包的话还不能是缺省的。
super的追溯不仅限于直接父类
如果某个属性或方法前面使用“this.”,那么先从本类中查找,如果未找到,会沿着继承关系往上找
如果某个属性或方法前面使用“super.”,那么先从直接父类中查找,如果未找到,会沿着继承关系往上找
如果某个属性或方法前面既没有“this.”,也没有“super.”,遵循就近原则,先从本类中查找,如果未找到,会沿着继承关系往上找
继承后的特点——成员方法
成员方法不重名时
如果子、父类中的方法不重名,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有定义对应的方法,若子类中存在就执行子类中定义的方法,若子类中没有定义就会沿着继承关系往上找有没有定义相应的方法,若父类中也没有则编译不通过。代码示例:
class Fu{
public void show(){
System.out.println("Fu类中的show方法执行");
}
}
class Zi extends Fu{
public void show2(){
System.out.println("Zi类中的show2方法执行");
}
}
public class ExtendsDemo04{
public static void main(String[] args) {
Zi z = new Zi();
//子类中没有定义show方法,但是可以找从父类继承的show方法去执行
z.show();
z.show2();
}
}
成员方法重名——重写(Override)
如果子、父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。
- 方法重写 :子类继承了父类,可以获得父类的成员变量和成员方法;可是当父类的某个方法不适合于子类本身的特征时,在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重写、覆写。在程序执行时,子类的方法将覆盖父类的方法。
代码如下:
class Fu {
public void show() {
System.out.println("Fu show");
}
}
class Zi extends Fu {
//子类重写了父类的show方法
public void show() {
System.out.println("Zi show");
}
}
public class ExtendsDemo05{
public static void main(String[] args) {
Zi z = new Zi();
// 子类中有show方法,只执行重写后的show方法
z.show(); // Zi show
}
}
重写的应用
子类可以根据需要,定义特定于自己的行为。既沿袭了父类的功能名称,又根据子类的需要重新实现父类方法,从而进行扩展增强。比如新的手机增加来电显示头像的功能,代码如下:
class Phone {
public void sendMessage(){
System.out.println("发短信");
}
public void call(){
System.out.println("打电话");
}
public void showNum(){
System.out.println("来电显示号码");
}
}
//智能手机类
class NewPhone extends Phone {
//重写父类的来电显示号码功能,并增加自己的显示姓名和图片功能
public void showNum(){
//调用父类已经存在的功能使用super
super.showNum();
//增加自己特有显示姓名和图片功能
System.out.println("显示来电姓名");
System.out.println("显示头像");
}
}
public class ExtendsDemo06 {
public static void main(String[] args) {
// 创建子类对象
NewPhone np = new NewPhone();
// 调用父类继承而来的方法
np.call();
// 调用子类重写的方法
np.showNum();
}
}
重写时,用到super.父类成员方法,表示调用父类的成员方法。
方法重写注意事项
方法名:必须完全一致
形参列表:必须完全一致
返回值类型:
如果是基本数据类型和void,必须一致
如果是引用数据类型,重写的方法的返回值类型 <= 被重写方法的返回值类型,Student<Person
修饰符:重写的方法的修饰符范围 >= 被重写方法的修饰符范围(public > protected > 缺省 > private)
被重写方法不能被
private、static、final修饰,如果跨包的话,修饰符缺省的也不能被重写,因为缺省的跨包不可见
继承后的特点——构造方法
首先我们要回忆两个事情,构造方法的定义格式和作用:
- 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
- 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。
- 子类不会继承父类的构造器,但是一定会调用父类的构造器
- 默认情况下,调用的是父类的无参构造,super()写或不写都会调用父类的无参构造,如果要写,必须在子类构造器首行
- 如果父类没有无参构造,必须在子类的构造器首行使用super(实参列表)显式调用父类的有参构造,否则编译报错
- super([形参列表]) 和 this([形参列表]) 都必须是在构造方法的第一行,所以不能同时出现。
代码示例:
class Father{
public Father(){
System.out.println("父类的无参构造");
}
}
class Son extends Father{
private String str;
private int num;
public Son(){
//隐含调用了super(); 子类的构造器中一定会调用父类的构造器,默认调用父类的无参构造
System.out.println("子类的无参构造");
}
public Son(String str){
//隐含调用了super()
this.str = str;
System.out.println("子类的有参构造1");
}
public Son(String str,int num){
//调用重载的构造器,隐含调用了super()
this(str);
this.num = num;
System.out.println("子类的有参构造2");
}
}
public class ConstructorTest {
public static void main(String[] args) {
Son s1 = new Son();
/*
父类的无参构造
子类的无参构造
*/
//Son s2 = new Son("java");
/*
父类的无参构造
子类的有参构造1
*/
Son s3 = new Son("java", 10);
/*
父类的无参构造
子类的有参构造1
子类的有参构造2
*/
}
}
Java继承后访问成员的特点的更多相关文章
- java继承关系中成员变量,构造方法,成员方法的关系
Java继承中的成员关系 A:成员变量 a:子类的成员变量名称和父类中的成员变量名称不一样,这个太简单写那个名字就访问那个名字! b:子类的成员变量名称和父类中的成员变量名称一样,这个怎么访问呢? 子 ...
- Java继承和访问修饰符
继承 概念:为了提取两个类中公共代码,可以使用继承抽取重复性的代码到一个公共类中,这个公共的类称为父类(super class).继承于父类的类称为子类(sub class). 关键字 ext ...
- Java 访问限制符 在同一包中或在不同包中:使用类创建对象的权限 & 对象访问成员变量与方法的权限 & 继承的权限 & 深入理解protected权限
一.实例成员与类成员 1. 当类的字节码被加载到内存, 类中类变量.类方法即被分配了相应内存空间.入口地址(所有对象共享). 2. 当该类创建对象后,类中实例变量被分配内存(不同对象的实例变量互不相同 ...
- C++入门经典-类成员的可访问性,继承后的可访问性
1:关键字public.private.protected说明类成员是共有的.私有的,还是保护的.这3个关键字将类划分为3个区域,在public区域的类成员可以在类作用域外被访问,而private区域 ...
- java 继承访问成员变量
package java09; //创建父类 public class Fu { int numFu = 10; int num =100; public void methodFu(){ Syste ...
- java:包、继承,访问修饰符
包 包(package) 用于管理程序中的类,主要用于解决类的同名问题.包可以看出目录. 包的作用 [1] 防止命名冲突. [2] 允许类组成一个单元(模块),便于管理和维护 [3] 更好的保护类.属 ...
- JAVA知识总结(三):继承和访问修饰符
今天乘着还有一些时间,把上次拖欠的面向对象编程三大特性中遗留的继承和多态给简单说明一下.这一部分还是非常重要的,需要仔细思考. 继承 继承:它是一种类与类之间的关系,通过使用已存在的类作为基础来建立新 ...
- C++继承后的函数访问权限
今天在写代码时发现对继承后的函数访问权限不太清楚,于是自己做了个测试: 1.头文件(test.h) 1 #include <iostream> 2 using namespace std ...
- java中用反射访问私有方法和私有成员[转]
转自: http://zhouyangchenrui.iteye.com/blog/470521 java的反射可以绕过访问权限,访问到类的私有方法和成员.可能这点会引起安全性的讨论.反射的使用帮助解 ...
随机推荐
- Dart语言之 异步支持
Dart类库有非常多的返回Future或者Stream对象的函数. 这些函数被称为异步函数:它们只会在设置好一些耗时操作之后返回,比如像 IO操作.而不是等到这个操作完成. async和await关键 ...
- Jenkins怎么安装?Jenkins控制台输出乱码怎么处理?Jenkins执行selenium脚本时浏览器不显示怎么处理?
今天我们来看一看Jenkins的安装. 首先我们看一下Jenkins是什么,能够干什么.Jenkins呢是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开 ...
- 设备管理的数据库路径是/storage/sdcard0/data/devuce-db
设备管理的数据库路径是/storage/sdcard0/data/devuce-db 数据库文件名全路径是/storage/sdcard0/data/devuce-db/device.db 数据库文件 ...
- scrapy基本用法
scrapy官方文档http://doc.scrapy.org/en/latest/ 一.scrapy安装 安装lxml:pip3 install lxml 安装wheel:pip3 install ...
- MacOS下SpringBoot基础学习
学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"springboot"获取视频和教程资料! b站在线视 ...
- Python os.fchmod() 方法
概述 os.fchmod() 方法用于改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限.高佣联盟 www.cgewang.com Unix上可用. 语法 fchmo ...
- [草稿]基于 Virtuoso 环境比较便捷的项目文件及权限管理方案
https://www.cnblogs.com/yeungchie/ 假设如下情况: 1 项目名称 Project_01 2 包含 4 名研发用户,user01 和 user02 为前端工程师,use ...
- loj #6247. 九个太阳 k次单位根 神仙构造 FFT求和原理
LINK:九个太阳 不可做系列. 构造比较神仙. 考虑FFT的求和原理有 \(\frac{1}{k}\sum_{j=0}^{k-1}(w_k^j)^n=[k|n]\) 带入这道题的式子. 有\(\su ...
- luogu P1446 [HNOI2008]Cards burnside引理 置换 不动点
LINK:Cards 不太会burnside引理 而这道题则是一个应用. 首先 一个非常舒服的地方是这道题给出了m个本质不同的置换 然后带上单位置换就是m+1个置换. burnside引理: 其中D( ...
- 当asp.net core偶遇docker二(打造个人docker镜像)
网络上的docker容器总有一些不尽人意的感觉,这个时候,就需要自己diy一个自用的. 比如我们想在163的mysql 5.7内diy一下,结果发现,这个不带vim,我想改造一个自用的mysql镜像, ...