继承
继承用关键字extends表示
译为拓展,子类是父类的拓展,写法如下
//人 :父类
public class Person {}
//Student 是 人 用继承 :子类(派生类)
public class Student extends Person{}
//Teacher 是 人 用继承 :子类(派生类)
public class Teacher extends Person{}
子类可以继承父类所有public方法,但private类方法不能使用,因为是私有的。protected(受保护的)和default(默认的)也不能被继承
java中,所有的类都默认直接或间接继承object类
快捷键:Ctrl+H 打开族谱
继承是类与类之间的一种关系。
!!!java中只有单继承,没有多继承
super关键词
this. 调用此类的东西
super. 调用父类的
import com.vvv.oop.demo02.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("王五");
}
}
父类
//父类
public class Person {
protected String name="张三";
}
子类
public class Student extends Person{
private String name="李四";
public void test(String name){
System.out.println(name);//王五
System.out.println(this.name);//李四
System.out.println(super.name);//张三
}
}
也可以调用方法(私有的:private不被继承)
//父类
public class Person {
public void print(){
System.out.println("Person");
}
}
//子类
public class Student extends Person{
public void print(){
System.out.println("Student");
}
public void test1(){
print();//Student
this.print();//Student
super.print();//Person
}
}
import com.vvv.oop.demo02.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test1();
}
}
无参构造
//父类
public class Person {
public Person() {
System.out.println("Person无参执行了");
}
}
//子类(派生类)
public class Student extends Person{
public Student() {
//隐藏代码:默认调用了父类的无参构造
super();//为隐藏的代码
//调用父类的构造器,必须要在子类构造器的第一行
System.out.println("Student无参执行了");
}
}
import com.vvv.oop.demo02.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
/*输出
Person无参执行了
Student无参执行了
*/
}
}
注意
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或构造方法中
- super和this不能同时调用构造方法(因为他两都必须在构造方法的第一个)
super和this
代表的对象不同
? this:本身调用者这个对象
? super:代表父类对象的应用
前提
? this:没有继承也可以使用
? super:只有在继承条件下才可以使用
构造方法
? this():本类的构造
? super():父类的构造
方法重写
重写都是方法的重写,与属性无关
public class B {
public static void test(){
System.out.println("B=>test()");
}
}
public class A extends B {
public static void test(){
System.out.println("A=>test()");
}
}
import com.vvv.oop.demo02.A;
import com.vvv.oop.demo02.B;
public class Application {
public static void main(String[] args) {
//方法的调用只和左边,定义的数据类型有关
A a=new A();
a.test();//调用A的方法
//输出A=>test()
//父类的引用指向了子类
B b=new A();
b.test();//调用B的方法
//输出B=>test()
}
}
去掉static才可重写
public class B {
public void test(){
System.out.println("B=>test()");
}
}
public class A extends B {
public void test(){
System.out.println("A=>test()");
}
}
import com.vvv.oop.demo02.A;
import com.vvv.oop.demo02.B;
public class Application {
public static void main(String[] args) {
A a=new A();
a.test();//调用A的方法
//输出A=>test()
B b=new A();//子类重写了父类的方法
b.test();//调用A的方法
//输出A=>test()
}
}
综上:静态和非静态的方法区别很大
因为静态方法(+static)是类的方法,非静态方法是对象的方法
没有static时,b调用的是对象的方法,而b是用A类new的,即b是A new出来的对象,所以调用A的方法
有static时,b调用的是B类的方法
静态方法只能被继承,不能被重写,只有非静态方法才可被重写
Alt+Insert后有Override Methods(重写方法)
//使用快捷键后
public class A extends B {
//Override 重写
@Override//注解:有功能的注释
public void test() {
super.test();//默认调用此方法,可以重写自己的方法
}
}
重写的条件
- 非静态方法,关键字为public
- 需要有继承关系,子类重写父类的方法
- 方法名和参数列表必须相同
- 修饰符:范围可以扩大但不可以缩小:public>protected>default>private
- 抛出的异常:范围可以被缩小,但不能扩大:ClassNotFoundException-->Exception(大)
重写,子类和父类的方法必要一致,方法体不同
为什么要重写:
父类的功能,子类不一定需要,或者不一定满足