目录
extends
继承的关键字为extends。
例如:public class Student extends People{ }
Student为子类,People为父类。子类继承父类后可以直接使用父类公共的属性和方法。
public class Test_03 { public static void main(String[] args) { Police p=new Police(); System.out.println(p.name); p.run(); } } class People{ public String name ="法外狂徒"; public void run(){ System.out.println(name+"逃跑失败了!"); } } class Police extends People{ }
继承的特点:
1:子类可以继承父类的属性和行为,但不可以继承父类的构造器。
2:Java是单继承模式,一个类只能继承一个直接父类
3:Java不支持多继承,但是支持多层继承
4:Java中所有类都是Object的子类
继承后,访问成员变量,成员方法遵循“就近原则”。
先在子类局部范围找,然后在子类成员范围中找,然后在父类成员范围找
访问成员方法
public class Test_01 {
public static void main(String[] args) {
Tiger t=new Tiger();
t.run();//Tiger中无run方法,就去找父类
}
}
class Animal{
public void run(){
System.out.println("动物再跑!");
}
}class Tiger extends Animal{
}
=====================================================================
public class Test_01 { public static void main(String[] args) { Tiger t=new Tiger(); t.run();//Tiger中有run方法,会运行子类中的run方法。 } } class Animal{ public void run(){ System.out.println("动物再跑!"); } } class Tiger extends Animal{ public void run(){ System.out.println("老虎再跑!"); } }-------------------------------------------------------------------------------------------------------------------------
public class Test_01 { public static void main(String[] args) { Tiger t=new Tiger(); t.go();//Tiger中有run方法,会运行子类中的run方法。如果子父类中有重名的成员,会优先使用子类,如果在子类中访问父类的成员使用super关键字 } } class Animal{ public void run(){ System.out.println("动物再跑!"); } } class Tiger extends Animal{ public void run(){ System.out.println("老虎再跑!"); } public void go(){ super.run(); } }
访问成员变量
public class Test_01 { public static void main(String[] args) { Tiger t=new Tiger(); t.showName();//showName方法中有name,则会输出“局部名” } } class Animal{ public String name="动物名"; } class Tiger extends Animal{ public String name="老虎名"; public void showName(){ String name="局部名"; System.out.println(name); } }-------------------------------------------------------------------------------------------------------------------------
public class Test_01 { public static void main(String[] args) { Tiger t=new Tiger(); t.showName();//无局部名时去子类成员范围内找,此时输出的是“老虎名” } } class Animal{ public String name="动物名"; } class Tiger extends Animal{ public String name="老虎名"; public void showName(){ //String name="局部名"; System.out.println(name); } }-------------------------------------------------------------------------------------------------------------------------
public class Test_01 { public static void main(String[] args) { Tiger t=new Tiger(); t.showName();//无局部名,子类成员范围也没有,此时去父类成员范围内找,输出“动物名” } } class Animal{ public String name="动物名"; } class Tiger extends Animal{ //public String name="老虎名"; public void showName(){ //String name="局部名"; System.out.println(name); } }-------------------------------------------------------------------------------------------------------------------------
public class Test_01 { public static void main(String[] args) { Tiger t=new Tiger(); t.showName(); } } class Animal{ public String name="动物名"; } class Tiger extends Animal{ public String name="老虎名"; public void showName(){ String name="局部名"; System.out.println(name); System.out.println(super.name); System.out.println(this.name);//如果在存在局部名的情况下,想要去访问当前子类对象的name时,加上一个this就行。同理加上一个super可以访问父类的成员变量。 } }
继承后的方法重写
注意方法重写与方法重载的区别
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
public class Test_02 { public static void main(String[] args) { newPhone hw=new newPhone(); hw.makeVideo(); hw.sendMessage(); } } class oldPhone{ public void sendMessage(){ System.out.println("发消息"); } public void makeVideo(){ System.out.println("打语音电话"); } } class newPhone extends oldPhone{ @Override //方法重写 public void sendMessage(){ super.sendMessage(); System.out.println("发短信"); } @Override //方法重写 public void makeVideo(){ super.makeVideo(); System.out.println("打视频电话"); } }
父类的私有方法不能被重写
class oldPhone{
private void sendMessage(){
System.out.println("发消息");
}
}
class newPhone extends oldPhone{
// @Override//此时子类重写的方法报错
// public void sendMessage(){
// super.sendMessage();
// System.out.println("发短信");
// }
}
子类重写父类方法时,访问权限必须大于等于父类。(public>protected>缺省>private)
一般来说把子类的权限写成和父类一样就可以了。
子类不能重写父类的静态方法,如果重写会报错。
子类继承父类后构造器的特点:
子类的所有构造器都会默认先访问父类的无参构造器,在执行自己。
public class Test_04 { public static void main(String[] args) { Son s1=new Son(); Son s2=new Son("张三"); } } class Son extends Father{ public String name; public Son(){ //super();//子类构造器的第一行默认都有super(); System.out.println("子类的无参数构造器被执行了!"); } public Son(String name) { this.name = name; System.out.println("子类的有参数构造器执行了!"); } } class Father{ public Father(){ System.out.println("父类的无参数构造器被执行了"); } }-------------------------------------------------------------------------------------------------------------------------
程序执行结果:
父类的无参数构造器被执行了
子类的无参数构造器被执行了!
父类的无参数构造器被执行了
子类的有参数构造器执行了!
在子类中访问父类有参数构造器
public class Test_01 { public static void main(String[] args) { Test_01Teacher t=new Test_01Teacher("张三",35); System.out.println(t.getAge()); System.out.println(t.getName()); } }
-----------------------------------------------------------------------------------------------------------------------
public class Test_01People { private String name; private int age; public Test_01People(){ } public Test_01People(String name, int age) { this.name = name; this.age = 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 class Test_01Teacher extends Test_01People{ public Test_01Teacher(String name,int age){ super(name, age); } }
如果父类中没有无参数构造器,只有有参数构造器,子类中写构造器时会报错。因为子类默认访问父类的无参数构造器。