父类和子类
父类可以称为超类(SuperClass),子类也可以称为派生类。
子类继承父类的使用格式:
class 子类 extends 父类 {}
例子:
class Father{
public void Fmethod() {
System.out.println("父类方法被调用");
}
}
class Son extends Father{
public void Smethod() {
System.out.println("子类方法被调用");
}
}
public class Java {
public static void main(String[] args) {
Son test = new Son();
test.Fmethod();
test.Smethod();
}
}
输出结果:
父类方法被调用
子类方法被调用
可以看到子类对象实例化后可以调用父类的方法,也就是说子类在父类的基础上扩充了更多的方法,不仅能够调用父类的方法,也能调用子类的方法。
子类对象实例化
继承时,子类要重用父类中的结构,在子类对象实例化的时候,子类会调用父类中的无参构造方法,先进行父类对象实例化,再进行子类对象实例化。
例子:
class Father{
public Father() {
System.out.println("父类构造方法被调用");
}
}
class Son extends Father{
public Son() {
System.out.println("子类构造方法被调用");
}
}
public class Java {
public static void main(String[] args) {
Son test = new Son();
}
}
输出结果:
父类构造方法被调用
子类构造方法被调用
从上面的例子可以明确地看到,主方法只有一个实例化语句,但输出结果先调用了父类的无参构造方法,然后调用了子类的无参构造方法。但其实实际上子类继承了父类,子类的构造方法中有一个隐藏的super()语句。
class Son extends Father{
public Son() {
super();
System.out.println("子类构造方法被调用");
}
如果写了super()语句则会明确的调用父类的构造方法,如果不写则会默认调用父类的无参构造方法。但当super()语句里带有参数时,则会调用有参数的父类构造方法。
例子:
class Father{
public Father() {
System.out.println("父类无参构造方法被调用");
}
public Father(int x) {
System.out.println("父类有参构造方法被调用");
}
}
class Son extends Father{
public Son() {
super(0);
System.out.println("子类构造方法被调用");
}
}
public class Java {
public static void main(String[] args) {
Son test = new Son();
}
}
输出结果:
父类有参构造方法被调用
子类构造方法被调用
父类如果没有无参构造方法,子类就必须要使用super()语句来调用父类的有参构造函数,并且super()语句必须放在子类构造方法的第一行。
继承限制
继承在使用时有一定的限制:
1.一个子类只能继承一个父类。
也就是不能多重继承,比如:
class a{}
class b{}
class c extends a,b{}
这样c类就继承了两个父类,但这样写就会出现错误,一个子类只能继承一个父类。
但是可以多层继承,多层继承就是c类继承b类,b类还可以继承a类,比如:
class a{}
class b extends a{}
class c extends b{}
2.在一个子类继承时,会继承父类所有的属性和方法,但是非私有的继承属于显式继承,而私有(private)属于隐式继承。
例子:
class Father{
private int x;
public void setter(int x) {
this.x = x;
}
public int getter() {
return x;
}
}
class Son extends Father{
public Son(int x) {
setter(x);
}
public int method() {
// System.out.println(x);
return getter();
}
}
public class Java {
public static void main(String[] args) {
Son test = new Son(0);
}
}
输出结果:
0
如果上述例子,有System.out.println(x)这句,则会报错,为什么呢?因为在父类中x为私有,所以不能直接访问,而如果没有这一句而是调用方法,则可以访问。
覆写
继承时子类可以对父类中的方法和属性(非private)进行覆写。
例子:
class Father{
public void method() {
System.out.println("父类方法");
}
}
class Son extends Father{
public void method() {
System.out.println("子类覆写父类方法");
}
}
public class Java {
public static void main(String[] args) {
Son test = new Son();
test.method();
}
}
输出结果:
子类覆写父类方法
如果想调用父类被覆写的方法,则可以在子类方法的首行使用super.方法名。
当然属性也可以被覆写。
例子:
class Father{
int shuxin = 100;
}
class Son extends Father{
String shuxin = "子类覆写父类属性";
public void method() {
System.out.println(super.shuxin);//调用父类方法就用super.方法名
System.out.println(shuxin);
}
}
public class Java {
public static void main(String[] args) {
Son test = new Son();
test.method();
}
}
输出结果:
100
子类覆写父类属性
覆写也是有限制的,经常接触到的访问权限有private,default(默认)和public三种,这三种权限大小为public>default>private。子类进行覆写时,权限不能比父类小,只能比父类大。如果父类的权限为public,则子类的权限只能是public,不能为default或者private。
final关键字
简单地说就是使用了final关键字的类,不能被继承;使用了final关键字的方法不能被覆写;可以用来定义全局常量(常量的内容不能更改)。
final关键字的使用格式;
final class test{}