一、概述
在继承关系当中,“子类就是一个父类”,也就是说,子类可以被当作父亲看待。例如父类是员工,子类是讲师,那么”讲师就是一个员工“关系。定义父类的格式:(一个普通的类定义)public class 父类名称{ //.....}定义子类的格式:public class 子类名称 extends 父类名称{ //.....}
首先创建一个demo01类,然后再创建一个员工类。
//定义一个父类,员工
public class Employee { public void method(){ System.out.println("方法执行!"); }}
//定义了一个员工的子类,讲师
public class Teacher extends Employee{}
在demo01当中创建一个子类对象:
//创建一个子类对象 Teacher teacher=new Teacher(); //teacher类当中虽然什么都没有写,但是会继承来自父类的method方法 teacher.method();
//定义了员工的另一个子类,助教
public class Assistant extends Employee{}
在demo01当中创建另一个子类助教的对象:
Assistant assistant=new Assistant(); assistant.method();
二、继承中成员变量访问的特点:
先创建一个子类和父类:
public class Fu { int numFu=10; int num=100;}
public class zi extends Fu{ int numZi=20; int num=200;}
测试类:
public class Demo02 { public static void main(String[] args) { //创建一个父类对象 Fu fu=new Fu(); System.out.println(fu.numFu);//只能使用父类的东西,没有任何子类的东西 zi Zi=new zi(); System.out.println(Zi.numFu);//10 System.out.println(Zi.numZi);//20 }}
子类和父类中都有num变量,当访问num时,访问谁?
在父子类的继承关系当中,如果成员变量重名,则创建子类对象时,访问有两种方式:直接通过子类对象访问成员变量: 等号左边是谁,就优先用谁,没有则向上找。
//等号左边是谁,就优先用谁 System.out.println(Zi.num);//优先子类,200 // System.out.println(Zi.abc);//到处都没有,编译报错!
间接通过成员方法访问成员变量: 该方法属于谁,就优先选谁,没有则向上找
在子类和父类中分别写一个方法:
public void methodFu(){ //使用的num是本类当中的num System.out.println(num); }
public void methodZi(){ //因为本类当中的有num,所以这里用的是本类当中的num System.out.println(num); }
demo02中:
//这个方法是子类的,优先用子类的,没有在向上找 Zi.methodZi();//200 //这个方法是在父类中定义的 Zi.methodFu();//100
三、区分子类方法中的重名:
在子类和父类中分别创建num变量:
public class Fu { int num=10;}
public class Zi extends Fu{ int num=20; public void method(){ int num=30; }}
局部变量 直接写成员变量名本类的成员变量 this.成员变量父类的成员变量 super.成员变量
在Zi类的方法中写:
public void method(){ int num=30; System.out.println(num);//30 局部变量 System.out.println(this.num);//20,本类的成员变量 System.out.println(super.num);//10,父类的成员变量 }
在测试类中创建对象:
public static void main(String[] args) { Zi zi=new Zi(); zi.method(); }
四、继承中成员方法的访问特点:
创建子父类的成员方法,并在测试类中创建对象访问:
public class Fu { public void methodFu(){ System.out.println("父类方法执行!"); }}
public class Zi extends Fu{ public void methodZi(){ System.out.println("子类方法执行!"); }}
public static void main(String[] args) { Zi zi=new Zi(); zi.methodZi(); zi.methodFu();}
在子类和父类当中创建同一个方法method,访问的是谁的对象?
父类方法:
public void method(){ System.out.println("父类方法执行!"); }
子类方法:
public void method(){ System.out.println("子类方法执行!"); }
在父类的继承关系当中,创建子类对象,访问成员方法的规则。 创建的对象是谁,就优先用谁,如果没有则向上找
zi.method();
注意事项:无论是成员方法还是成员变量,如果没有,都是向上找,绝对不回向下找子类的。
五、继承中方法的覆盖重写
重写(Override)概念:在继承关系当中,方法的名称一样,参数列表也一样。重写(Override):方法的名称一样,参数列表「也一样」。覆盖。覆写重载(OverLoad):方法的名称一样,参数列表『不一样』。方法的覆盖重写特点,创建的是子类对象,则优先用子类的方法。
方法覆盖的注意事项:1、必须保证父子类之间方法的名称相同,参数列表也相同。@Override,写在方法前面,用来检测是不是有效的正确覆盖重写。
父类和子类都创建method()方法,子类上面加入@Override方法不会报错。
public void method(){ }
@Override public void method(){ }
2、子类方法的返回值必须小于等于父类方法的返回值范围。Object类是所有类的公共最高父类(祖宗类)
父类使用Object,子类使用String ,Object大于String。
public Object method(){ return null; }
public String method(){ return null; }
3、子类方法的权限必须大于等于父类方法的权限修饰符。小扩展提示:public > protected(default)> private备注:(default)不是关键字default,而是什么都不写,留空。
父类:
public Object method(){ return null; }
子类可以是:
public String method(){ return null; } private String method(){ return null; } String method(){ return null; }
应用案例:
phone类:
//本来的老手机public class Phone { public void call(){ System.out.println("打电话"); } public void send(){ System.out.println("发短信"); } public void show(){ System.out.println("显示号码"); }}
newphone类:
//定义一个新手机,使用老手机作为父类 public class NewPhone extends Phone { @Override public void show() { super.show(); //本来的方法可以不用写,添加新功能就行 System.out.println("显示姓名"); System.out.println("显示头像"); }}
测试类:
public class Demo03 { public static void main(String[] args) { Phone phone=new Phone(); phone.call(); phone.send(); phone.show(); System.out.println("============="); NewPhone newPhone=new NewPhone(); newPhone.call(); newPhone.send(); newPhone.show(); }}
六、继承中构造方法的访问特点:
继承关系当中,父子类构造方法的访问特点:1、子类构造方法当中有一个默认隐含的“super”调用,所以一定是先调用父类构造,然后执行子类构造。
程序如下:
public class Fu { public Fu(){ System.out.println("父类构造方法!"); }}
public class Zi extends Fu{ public Zi(){ //super(); 在调用父类无参构造方法。 System.out.println("子类构造方法!"); }}
public class Demo04Constructor { public static void main(String[] args) { Zi zi=new Zi(); }}
2、子类构造可以通过super关键字来调用父类重载构造。
有参构造:
public class Fu { public Fu(){ System.out.println("父类无参构造方法!"); } public Fu(int num){ System.out.println("父类有参构造方法!"); }}
public class Zi extends Fu{ public Zi(){ super(20); //super(); 在调用父类无参构造方法。 System.out.println("子类构造方法!"); }}
3、super的父类构造调用,必须是子类构造方法的第一个语句。
public class Zi extends Fu{ public Zi(){ super(20); //super(); 在调用父类无参构造方法。 System.out.println("子类构造方法!"); } public void method(){ // super();//错误写法,只有子类构造方法,才能调用父类构造方法 }}
七、super关键字的三种用法:
父类:
public class Fu { int num=10; public void method(){ System.out.println("父类方法!"); }}
1、在子类的成员方法中,访问父类的成员变量。
public class Zi extends Fu{ int num=20; public void methodZi(){ System.out.println(super.num);//父类中的num }
2、在子类的成员方法中,访问父类的成员方法。子类中:
public void method(){ super.method();//访问父类中的method System.out.println("子类方法!"); }
3、在子类的构造方法中,访问父类的构造方法。
public Zi(){ super(); }
八、this关键字:
super关键字用来访问父类内容,而this关键字用来访问本类内容,用法也有三种:1、在本类的成员方法中,访问本类的成员变量。
父类:
public class Fu { int num=30;}
子类:
public class Zi extends Fu{ int num=20; public void showNum(){ System.out.println(num);//局部变量 System.out.println(this.num);//本类中的成员变量 System.out.println(super.num); }}
2、在本类的成员方法中,访问本类的另一个成员方法。
public void methodA(){ System.out.println("AAA"); } public void methodB(){ this.methodA(); System.out.println("BBB"); }
3、在本类的构造方法中,访问本类的另一个构造方法。这种方法注意:this.(...)调用也必须是构造方法的第一个语句,唯一一个且super和this调用不能同时使用,两者都是唯一的。
public Zi(){ this(123);//本类的无参构造,调用本类的有参构造。 } public Zi(int n){ }
九、java继承的特点:
1、Java只支持单继承,不支持多继承。
//一个类只能有一个父类,不可以有多个父类。class C extends A{} C extends A,B... //error
2、Java支持多层继承(继承体系)。
class D{}class E extends D{}classf extends E{}
3、子类和父类是一种相对的概念。