通过定义子类或扩展超类向类中添加功能的能力,是面向对象编程范式的核心。
关键字 extends 表示扩展。final修饰符声明类时,表示该类无法被扩展或定义子类
public class PlaneCircle extends Circle { //自动继承Circle类的字段和方法 private final double cx, cy; //新构造函数,用于初始化新字段 public PlaneCircle(double r, double x, double y) { super(r); //调用父类的构造方法Circle() this.cx = x; this.cy = y; } public double getCentrex(){ return cx;} public double getCentrey(){return cy;} //新方法,检查点是否在圆内 public boolean isInside(double x, double y) { double dx = x - cx, dy = y - cy; double distance = Math.sqrt(dx*dx + dy*dy); return (distance < r) ; } }
Circle和PlaneCircle是自己定义的类
1.创造类的实例时,Java一定会调用这个类的构造方法。
2.还保证一定会调用父类的构造方法
3.如果构造方法第一个语句没有用this或者super显式调用构造方法,javac编译器会插入super()没有参数的。
4.如果类没有构造方法,java会隐式为该类添加一个默认的构造方法。
x //C类的x字段 this.x //C类的x字段 super.x //B类的x字段 ((B)this).x //B类的x字段 ((A)this).x //A类的x字段 super.super.x //非法用法 c.x //C类的x字段 ((B)c).x //B类的x字段 ((A)c).x //A类的x字段
如果类中定义的某个实例方法和父类的某个方法有相同的方法、返回值类型和参数,那么这个方法会覆盖(override)父类中对应的方法。在这个类调用这个方法时,调用的是最新定义的方法。而不是父类中的旧方法。
class A{ //定义类A int i = 1; //实例字段 int f(){retrun i;} //实例方法 static char g(){return 'A';} //类方法 } class B extens A{ //定义A的子类 int i = 2; //遮盖A的字段 int f(){return -i;} //覆盖A类的方法f static char g(){return 'B';} //遮盖A类的类方法g() } public class OverrideTest{ public static void main(String args[]){ B b = new B(); //创建B类对象 System.out.println(b.i); //打印2 System.out.println(b.f()); //打印-2 System.out.println(b.g()); //打印B System.out.println(B.g()); //调用B.g()更好的方式 A a= (A) b; //把b校正成A类的实例 System.out.println(a.i); //打印1 System.out.println(a.f()); //打印-2,引用的是B.f() System.out.println(a.g()); //打印A System.out.println(A.g()); //调用A.g()更好的方式 } }
使用super关键字
class A{ int i = 1; //被子类B遮盖的实例字段 int f(){return i;} //被子类B覆盖的实例方法 } Class B extends A{ int i; //遮盖A的字段i int f() //覆盖A类的方法f() { i = super.i + 1; //读取A.i return super.f() + i; //调用A.f() } }