Java通过extends关键字来实现,实现继承的类被称为子类,被继承的类成为父类或基类、超类。
子类对父类的扩展,子类是一种特殊的父类。Java的子类不能获得父类的构造器
class FatherClass{ public void fatherMethod(){ System.out.println("fatherMethod"); } } public class ExtendsClass1 extends FatherClass{ public static void main(String[] args){ ExtendsClass1 ec = new ExtendsClass1(); //获得父类的方法 ec.fatherMethod(); } }
如果一个类没有指定父类,则默认Object类,Object是所有类的父类,要么是直接父类,要么是间接父类。
重写父类的方法
class FatherClass{ public void fatherMethod(){ System.out.println("fatherMethod"); } } public class ExtendsClass1 extends FatherClass{ public void fatherMethod(){ System.out.println("重写了父类的方法 ,sonMethod"); } public static void main(String[] args){ ExtendsClass1 ec = new ExtendsClass1(); //这里子类重写了父类的方法,运行的是子类的方法 ec.fatherMethod(); } }
子类包含与父类方法同名的现象称为方法重写,override,也被称为方法覆盖。
方法的重写要遵循两同两大一小原则,两同:方法名相同,形参列表相同;两小,子类方法返回值类型比父类方法返回值类型更小或相等,子类方法声明抛出的异常比父类的更小或相等。一大,子类方法的访问权限比父类的大。覆盖方法和被覆盖方法要么都是实例方法,要么都是类方法,不能一个是类方法一个是实例方法。
当子类覆盖父类方法之后,子类无法方法父类的方法。可以使用super关键字或父类类名调用父类中被覆盖的方法。
class FatherClass{ public void fatherMethod(){ System.out.println("fatherMethod"); } } public class ExtendsClass1 extends FatherClass{ public void fatherMethod(){ //System.out.println("重写了父类的方法 ,sonMethod"); //super调用父类的方法 super.fatherMethod(); } public static void main(String[] args){ ExtendsClass1 ec = new ExtendsClass1(); ec.fatherMethod(); } }
super是Java提供的一个关键字,用于限定该对象调用它从父类继承得到的实例变量或方法。this不能出现在static方法中,super也不能出现在static修饰的方法中。static修饰的方法是属于类的。
class FatherClass{ static int a = 18; } public class ExtendsClass2 extends FatherClass{ static int a = 19; public static void main(String[] args){ //这里的是子类的值 System.out.println("子类a的值" + a); //super不能再static修饰的方法中 System.out.println(super.a); } }
class FatherClass{ int a = 18; public void method(){ System.out.println("父类a的值" + a); } } public class ExtendsClass2 extends FatherClass{ int a = 19; public void method(){ System.out.println("子类a的值" + a); System.out.println("子类覆盖父类的方法,输出父类的值" + super.a); } public static void main(String[] args){ ExtendsClass2 ec = new ExtendsClass2(); ec.method(); } }
class FatherClass{ int a = 18; public void method(){ System.out.println("父类a的值" + a); } } public class ExtendsClass2 extends FatherClass{ int a = 19; public void method(){ //子类方法中调用父类的方法 super.method(); } public static void main(String[] args){ ExtendsClass2 ec = new ExtendsClass2(); ec.method(); } }
父类私有方法和变量子类不能继承,也无法访问。如果子类定义相同的方法和变量,和父类的是不一样的。
class FatherClass{ private int a = 100; private void method(){ Sytem.out.println("父类私有方法"); } } public class ExtendsClass3{ int a = 200; public void method(){ System.out.println("子类方法,不是从父类继承的"): } }
子类调用父类的构造器
子类构造器执行的第一行super显式调用父类构造器,系统将根据super调用里传入实例列表调用父类对应的构造器;子类构造器执行体的第一行代码使用this显式调用本类中重载的构造器,系统将根据this调用里传入的实参列表调用本类中的另一个构造器,执行本类中另一个构造器时会调用父类构造器;子类构造器执行体中既没有super调用,也没有this调用,系统将会在执行子类构造器之前隐式调用父类无参数构造器。