(25)继承中成员变量、函数中覆盖、构造函数的理解
来源:互联网 发布:如何选择净水器 知乎 编辑:程序博客网 时间:2024/06/05 11:46
一、继承思想的引出
将学生和工人的共性描述提取出来,单独进行描述
只要让学生和工人与单独描述的这个类有关系,就可以了。
二、继承作用
1.提高了代码的复用性
2.让类与类之间产生了关系,有了这个关系,才有了多态的特性
注意:①千万不能为了获得其他类的功能,简化代码而继承
必须是类与类之间所属关系才可以继承,所属关系是 is a
②java中只支持单继承,java支持多重继承
多继承容易带来安全隐患:当多个父;类中定义了相同功能,当功能内容不同时,子类对象不确定运行哪一个
但是java保留这种机制,用另一种体现形式来完成表示,多实现
例如:
class A
{
void show(){
System.out.println("a");
}
}
class B
{
void show(){
System.out.println("b");
}
}
class C extends A,B{}
C c=new C();
c.show();//不确定调用哪个类中的同名函数
三、如何使用一个继承体系中的功能呢?
想要使用体系,先查阅父类的描述,因为父类中定义的是该体系中共性功能。通过了解共性功能,就可以知道该体系的基本功能
这个体系已经基本可用了
四、具体调用创建对象
在具体调用时,要创建最子类的对象。理由:①有可能父类不能创建对象(如抽象类)②创建子类对象可以使用更多的功能,也包括基本的都可以使用
三四总结:查阅父类功能,创建子类对象使用功能
类中成员:
1.变量
如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量用this,子类要访问父类中的同名变量用super
super的使用和this的使用几乎一致。
this 代表的是本类对象的引用。super代表父类对象的引用
简单分三种情况:①全私有②非私有③无重名。
public class person {public String country;private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}} public String country; private String name; public void study() { System.out.println("good study"); } public String getName() { return name; } public void setName(String name) { this.name = name; } /* * 子类成员和父类私有成员同名,若直接使用,使用的是子类变量this.name * 要使用父类变量,则用到super关键字,super.name,因为一个类中定义的属性应该私有 * (private),所以要用到getter方法super.getName() * */ public void show() { System.out.println(name); System.out.println(super.getName()); //System.out.println(getName());这样写也可以 } /* * 子类成员和父类非私有成员同名 */ public void show1() { System.out.println(this.country); System.out.println(super.country); } /* * 子类成员变量中无同名的,继承父的 */ public void show2() { System.out.println(super.getAge()); } public static void main(String[] args) { worker w=new worker(); w.setName("张三"); /* * 子类成员和父类私有成员同名 */ w.show(); /* * 子类成员和父类非私有成员同名 */ w.country="cn"; w.show1(); /* * 子类成员变量中无同名的,继承父的 */ w.show2(); }}
2.函数
对新写功能,没啥可说的,主要说下覆盖
当子类出现和父类一模一样的函数时,当子类对象调用该函数时,会运行子类函数的内容。
如同父类的函数被覆盖一样。这种情况是函数的另一个特性:重写(覆盖)
当子类继承了父类,沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致(覆盖的条件)
这时,没有必要定义新功能,而是使用覆盖特殊,保留父类的功能定义,并重写功能内容。
覆盖的作用:提高程序的扩展性
举个栗子:对(子类虽具备该功能,但是功能的内容却和父类不一致)理解
父类:人 speak(){s.o.p(“会说话”)}
子类:英国人 speak(){s.o.p(“会说英国话”)}
都是说话,没必要定义新的功能,覆盖即可
举个栗子:对提高程序的扩展性的理解
手机不断升级,不能修改源码,因为调用等会带来更多的修改。对来电显示功能进行拓展
父类:手机 show(){ s.o.p("numer")}
子类:新型手机 show(){ s.o.p("numer");
s.o.p("picture");
s.o.p("name");
}
对函数的功能进行拓展填充
父:public void show () {
System.out.print("country="+country);
System.out.print(" name="+name);
System.out.print(" age="+age);
}
子:public void show () {
super.show();//有些被覆盖函数的内容,在覆盖函数中也可以用,调用方法super.
若不加super就会是死循环,发生内存溢出
System.out.print(" salary="+salary);
}
写覆盖时的注意事项:
①子类覆盖父类,必须保证子类函数权限大于等于父类函数权限,才可以覆盖,否则编译失败
②静态只能覆盖静态的。(加载类时,非静态不加载)【知道即可,编程不用】
记住:重载:只看同名函数的参数列表
重写:子父类方法要一模一样(“三同一不低” 子类和父类的方法名称,参数列表,返回类型必须完全相同,而且子类方法的访问修饰符的权限不能比父类低)
③编程注意一个问题
父: int show(){执行语句;}
子:void show ( ){执行语句;}
子.show();//会出现编译错误。首先这不是覆盖,子继承父类,子类此时相当于有两个函数int show(){} void show(){}
虚拟机不知道执行哪个,所以出现编译错误。
3.构造函数
①特点:在对子类对象进行初始化时,父类的构造函数也会执行,那是因为子类的所有构造函数默认第一行有一条隐式的语句super()
(若重载了无参构造函数,则执行这个)
若父类重载了含参的构造函数(就不再含无参隐式了),则子类构造函数中,就不再含隐式语句super(),此时,必须指定要调用父类哪个构造函数。
②为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据初始化的。
如果要访问父类中指定的构造函数,可以通过手动定义super语句来指定(若写super()写在子构造函数的第一行)
③小应用:对访问父类中指定的构造函数,可以通过手动定义super语句来指定理解
父:class person
person(String name){this.name=name;}//构造函数
void show(){}
子:class strudent extends person
strudent(String name){
要执行这条语句this.name=name;,因为父类已经完成了这个函数,子类就可以继承或者在方法体中调用这个方法
所以可以用super(name)来完成,子构造函数内调用父构造函数不用.
}
void method(){ super.show(); //子普通构造函数调用父普通构造函数, super. }
④this(),super(),若写只能写在构造函数的第一行
就出现一个问题,若两者在子类中都想写,应该怎么办?
父:person
person(){ 执行语句;}
person(int x) {执行语句;}
子:student
student(){执行语句;}//含隐式的suer()
studetn(int x){this();执行语句;}
student s=new student(2);//其实this(),super(),都执行到了。
结论:子类的所有构造函数,默认都会访问父类中无参数的构造函数。因为子类每一个构造函数内的第一行都有一句隐式super();
当父类中没有空参数的构造函数时,子类需要通过super语句或者this语句来指定要访问父类中的构造函数 。
当然:子类的构造函数第一行也可以手动指定this语句来访问本类的构造函数。
子类中至少有一个构造函数会访问到父类中的构造函数
- (25)继承中成员变量、函数中覆盖、构造函数的理解
- java继承中,成员变量的覆盖
- java继承中,成员变量的覆盖
- java继承中,成员变量的覆盖
- java继承中,成员变量的覆盖
- 在构造函数的参数化列表中调用基类构造函数初始化继承来的成员变量
- 在构造函数的参数化列表中调用基类构造函数初始化继承来的成员变量
- C++继承中覆盖和隐藏基类成员变量或成员函数
- C++继承中覆盖和隐藏基类成员变量或成员函数
- C++中继承的成员变量的覆盖/重写
- 从虚函数的内存构造谈C++继承中函数的覆盖与隐藏
- JAVA反射中类的构造函数,成员变量,成员方法的使用
- JAVA中继承时成员变量和成员函数的区别
- 深刻理解继承中构造函数和析构函数
- 静态成员(成员函数+数据成员)继承中同样存在覆盖基类,而非共存子类
- 继承、多态——成员变量、成员函数、构造函数(this、super)
- java中成员变量、代码块、构造函数执行顺序
- 构造函数中成员变量初始化顺序问题
- php动态导出数据成Excel表格
- 机器学习之利用PCA来简化数据
- 面向对象1
- 一个开源的社会化编程项目
- Javascript基础(四)作用域和闭包
- (25)继承中成员变量、函数中覆盖、构造函数的理解
- 终于下手,Ubuntu 17.10 用 GDM 取代 LightDM
- safai上jquery动态设置select默认值不成功的问题
- java语言编写的人工智能小测试
- java中操作Oracle clob数据出现的连接关闭问题
- Java设计模式透析之 —— 模板方法(Template Method)
- 7招帮你释放Ubuntu磁盘空间
- 读/写视频文件
- Android动画