1 继承
1.1 概念
当一个新类拥有一个现有的类的所有成员时 此时可以让此新类从现有的类 派生、衍生
新类:子类
现有的类:父类、根类、超类
继承关键字:extends
继承格式:class 子类 extends 父类{ }
特点:
1 子类继承父类 父类没有任何影响
2 子类中拥有父类中定义的所有成员
3 子类不能继承父类的构造方法
4 子类可以拥有一些父类没有的成员–子类特有成员
5 子类继承了父类的私有成员 但不能直接使用 只能通过父类的方法间接来使用
6 子类可以根据需求 重新定义父类的已有成员
子类重新定义父类的成员变量 要求:变量名相同即可
子类重新定义父类的成员方法 要求:返回值类型相同 方法名相同 参数列表相同(方法声明完全相同) 重写override
7 一类如果没有继承其他类 默认继承Object类 :Object类----上帝类
8 java只支持类与类之间的单继承:一个类只能有一个直接父类 但可以有多个间接父类
继承:类与类之间创建关联关系 实现类的复用
public class Demo02Extends {
public static void main(String[] args) {
Fu02 f1=new Fu02(); //父类对象
Zi02 z1=new Zi02(); //子类对象
System.out.println(z1.a+":"+z1.b+":"+z1.c);
z1.show();
System.out.println(z1.a);
z1.smoke();
}
}
class Fu02 extends Object{//一类如果没有继承其他类 默认继承Object类
int a=11;
int b=13;
void show() {
System.out.println(this.k);
}
void hai() {}
public Fu02() {
super();
}
public Fu02(int a, int b) {
super();
this.a = a;
this.b = b;
}
private int k=1;//私有成员:只能在本类中访问
String enjoy="打牌";//此属性要被子类重新定义
void smoke() {//此方法要被子类重新定义--重写
System.out.println("水烟袋!");
}
}
class Zi02 extends Fu02{
//int a=-1;//子类重新定义
String a="aaaa";
int c=14;//子类特有
void hehe() {}
void show() {//子类重新定义
System.out.println(a+":"+b+":"+c);
}
String enjoy="打游戏";//子类重新定义:属性名相同即可
//父类的方法 无法满足子类的需求 子类对父类的方法进行改进--修改方法体
void smoke() {//从新定义父类的方法(不能满足子类需求)---重写--方法声明相同
System.out.println("过滤嘴!");
}
}
1.2 继承练习
- 定义子类时:分清此成员是子类特有 还是 子类重新定义
- 子类对象调用成员时:分清是子类特有、子类重新定义、父类继承
public class Demo04 {
public static void main(String[] args) {
Demo04Zi zi=new Demo04Zi();
System.out.println(zi.a);//子类重写定义的a:::从父类继承的a被隐藏
System.out.println(zi.b);//子类从父类继承的b
System.out.println(zi.c);//子类特有的 c
zi.show();//子类重写后的show:::从父类继承的show被隐藏
zi.hai();//子类从父类继承的hai
zi.hehe();//子类特有
}
}
//创建父类:提取子类的共同成员 形成父类
class Demo04Fu{
int a=1;
int b=2;
void show() {
System.out.println("父类:::show");
}
void hai() {
System.out.println("父类:::hai");
}
Demo04Fu(int a){}
}
class Demo04Zi extends Demo04Fu{
int a=11;//子类重新定义
int c=12;//子类特有
void show() {//重写
System.out.println("子类:::show");
}
void hehe() {//子类特有
System.out.println("子类:::hehe");
}
Demo04Zi(int a){
super(a);//调用父类的构造方法
}//Implicit super constructor Demo04Fu() is undefined. Must explicitly invoke another constructor
Demo04Zi(){
super(1);//所有的子类构造方法第一个语句必须是super(参数列表) 来调用父类的构造方法
}
}
2 super
this: 当前对象
使用场景1:方法中当成员变量与局部变量重名时 变量名默认指向局部变量
通过this.变量名来指向成员变量
注意:方法中成员前面默认有this.
使用场景2: 构造方法之间的相互调用 通过this(参数列表);
// this(参数列表)必须是当前方法的第一个语句
super: 父类的; 超级的
使用场景1:当子类重新定义父类成员时 从父类继承的成员会被隐藏 (子类方法中调用这些成员时 默认指的是重新定义后的)
通过super.成员来调用父类被隐藏的成员
子类方法中调用父类成员:前面默认有super.
使用场景2: 所有的子类构造方法的默认通过super()调用父类无参数的构造方法
如果父类没有无参数的构造方法 需要显式通过super(参数列表)来调用父类有参数的构造方法
// 注意:super(参数列表)必须是第一个语句
package com.zhiyou100.day09;
public class Demo05Super {
public static void main(String[] args) {
//Demo05Zi zi=new Demo05Zi();
//zi.hehe();
Demo05Zi zi=new Demo05Zi(1.1);
}
}
class Demo05Fu{
int a=1;
int b=2;
void show() {
System.out.println("父类:::show");
}
void hai() {
System.out.println("父类:::hai");
}
//-----------构造方法
Demo05Fu(int a){}
Demo05Fu(){
System.out.println("Demo05Fu()");
}
}
class Demo05Zi extends Demo05Fu{
int a=11;//子类重新定义
int c=12;//子类特有
void show() {//重写
System.out.println("子类:::show");
}
void hehe() {//子类特有
//System.out.println("子类:::hehe");
System.out.println("a="+a);
System.out.println("super.a="+super.a);//调用父类的a
show();//调用的子类
//重写后的show
super.show();//调用父类的show
System.out.println(b+":"+super.b);
super.hai();
}
//------------构造方法
Demo05Zi(int a){
super(a);//调用父类的构造方法
}//Implicit super constructor Demo04Fu() is undefined. Must explicitly invoke another constructor
Demo05Zi(){
super(1);//所有的子类构造方法第一个语句必须是super(参数列表) 来调用父类的构造方法
}
Demo05Zi(double d){
//默认super()调用父类无参数的构造方法
System.out.println("Demo05Zi(double d)");
}
}