Java的继承
- 继承的本质是对一批类的抽象。
- extends关键字,意为拓展,其内子类是对父类的扩展。public class Student extends Person,意为Student类继承了Person的所有公开属性,以及方法。
- 继承属于类之间的一种关系,此外还有依赖、组合聚合等。
- Java中只有单继承,没有多继承,就是一个子类只能有一个父类。
- 修饰符:
- public:公共的 可继承
- private:私有的 不可继承
- default:默认的 可继承
- protected:受保护的 不可继承
- Ctrl + H可以调出当前类的继承关系。
- 在Java中所有的类都默认继承Object类。
继承简单实例:
Student类:
//学生 is Person 属于Person的子类,派生类
public class Student extends Person{
}
Person类:
//父类
public class Person {
public int money = 10_0000_0000;
private int age = 88;
protected String name="wangduoyu";
public void say(){
System.out.println("say something");
}
}
main方法:
student.say();
System.out.println(student.money);
//System.out.println(student.age); 私有属性虽然被继承,但是不能直接调用
//System.out.println(student.name); 受保护的属性也被继承,但是不能直接调用
Person person = new Person();
person.getClass();
super方法
- 可以调用父类中受保护的属性,而且必须在构造方法的第一个。
- 子类在实例化过程中,会默认调用父类的构造器,随后生成自己的无参构造器。并且调用父类的构造器必须在子类构造器的第一行。
- 如果父类中不存在无参构造器,那么所有的子类也将无法使用无参构造器。同时如果需要调用父类的有参构造器,那么所有子类中都必须存在有参构造器。
- super和this不能同时调用构造方法,因为两个都必须在构造器的第一行。并且super无法在构造器外使用。
实例:
Person类:
//父类
public class Person {
// public int money = 10_0000_0000;
// private int age = 88;
// protected String name="wangduoyu";
// public void say(){
// System.out.println("say something");
// }
// public Person() {
// System.out.println("Person无参执行了");
// }
public Person(String name) {
System.out.println(name);
}
protected String name = "kuang";
public void print(){
System.out.println("Person");
}
}
/*
Student student = new Student();
student.say();
System.out.println(student.money);
//System.out.println(student.age); 私有属性无法继承
//System.out.println(student.name); 受保护的属性也无法继承
Person person = new Person();
person.getClass();
*/
Student类:
//学生 is Person 属于Person的子类,派生类
public class Student extends Person{
private String name ="ccc";
// public Student() {
// //super(); //此处默认存在这样的一个语句,调用了父类的构造器,不需要自己写。
// System.out.println("Student无参执行了");
// }
public Student(String name) {
super(name);
System.out.println(this.name);
}
public void print(){
System.out.println("Student");
}
public void test1(){
print();
this.print();
super.print();
}
public void test(String name){
System.out.println(name); //形参传进来的name
System.out.println(this.name); //这个类的自有属性name
System.out.println(super.name); //super可以调用父类中受保护的属性。
}
}
测试类main方法:
Student student1 = new Student("awddawd"); // Person无参执行了 Student无参执行了
//此处表明子类在实例化过程中,会默认调用父类的构造器,随后生成自己的无参构造器。并且调用父类的构造器必须在子类构造器的第一行。
//student.test("shei"); // shei,ccc,kuang
// student.test1(); //Student ,Student, Person
方法重写
- 重写需要有继承关系,子类重写父类的方法。
- 特征:
- 1.方法名必须相同。
- 2.参数列表必须相同。
- 3.修饰符范围可以扩大,但不可以缩小。 范围对比:public>protected>default>private
- 4.重写可能会抛出异常,范围可以被缩小但不能扩大。
- 重写的应用:父类的功能子类不完全需要和符合要求。
- 重写都是方法的重写,与属性无关。
- Alt+insert 可以调出方法重写,即override。
- 静态方法只能被继承,无法被重写,因为其同main方法一同在最初被加载了。
- 只能重写public的方法,private无法重写,protected同理。
- 当子类中使用重写创建方法时,默认继承父类的方法。当对子类实例化时,创建出的对象调用该方法是调用的父类方法,如果自己写则调用自写方法。当父类使用子类实例化时,所创建出的对象属于子类创建而出,因此使用方法重写会重写父类的方法,也即是此时的父类对象调用的是子类的方法。
- 首先,静态方法无法被重写,那么子类父类中有同名方法,并且父类使用子类实例化创建对象时,该对象所调用的仍旧是父类中的静态方法。而非静态方法中,父类方法会被重写,因而调用的是子类方法。
实例:
A类:
public class A extends B{
@Override //重写
public void test() {
super.test(); // 默认调用父类的方法
System.out.println("222");
}
}
B类:
public class B {
public void test(){
System.out.println("B>=test()");
}
}
main方法:
A a = new A();
a.test();
//父类的引用指向了子类。
B b =new A(); //子类重写了父类的方法
b.test();
//输出结果为B>=test() 222 B>=test() 222