目录
类的继承
1.继承的概念
由一个已有类定义一个新类,称为新类继承了已有类。被继承的已有类称为父类,而所有定义的新类就称为子类。通过继承,子类拥有父类的所有成员,包括成员变量和成员方法。子类可以定义新的成员变量和成员方法,也可以对父类中的成员变量和方法进行更改使得类的功能可以扩充。
在Java中,一个类只能继承一个父类,这称为单继承。但是一个父类可以被多个子类继承,而每个子类又可以作为父类让其他的子类继承。Object类是所有类的父类,它定义了所有对象都具有的基本属性和行为。但是在定义类时,即使没有指明Object为它的父类,Java也会自动将其定义为Object的子类。
2.继承的实现
声明子类
声明子类的格式是:
[修饰符] class 类名 extends 父类名 {
成员变量声明部分;
成员方法声明部分;
}
继承原则
类的继承原则主要有以下4条:
(1)子类继承父类的成员变量,包括实例成员变量和类成员变量。
(2)子类继承父类除构造方法以外全部成员方法,包括实例成员方法和类成员方法。
(3)子类不能继承父类的构造方法。子类需要声明自己的构造方法。
(4)子类可以重新声明父类的成员(成员变量和成员方法)。
父类成员的访问权限
子类虽然继承了父类的成员变量和方法,但并不是对父类所有成员变量和成员方法都具有访问权限。Java中子类访问父类成员的权限有以下限制:
(1)子类对父类的private成员没有访问权限,即子类中的方法不能直接引用父类的private变量,也不能直接调用父类的private成员方法。
(2)子类对父类的public和protected成员具有访问权限。
(3)子类对父类的缺省的成员的访问权限分两种情况:对位于同一个包中的具有访问权限;否则没有访问权限。
类的成员访问权限体现了类封装,即如果想类成员仅自己使用,则声明为private;如果想要让子类使用,则声明为protected;若想让所有的类都使用,则声明为public。
public class Person{
private String name;
private int age;
public void SetName(String myName){
name = myName;
}
public void SetAge(int myAge){
age = myAge;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
public class Student extends Person{
protected String grade;
Student(String SName,int SAge,String SGrade){
//因为在父类中name和age是private,所以不能直接调用,需要使用父类的方法来调用
SetName(SName); //若是name=SName,则错误
SetAge(SAge); //若是age=SAge,则错误
grade = SGrade;
}
public static void main(String args[]){
Student zhangsan = new Student("张三",18,"大一");
}
}
3.super和this
在子类中可以声明与父类同名的成员变量以及成员方法,为了指明是引用父类中的成员可以使用super关键字,为了指明是引用子类中的成员可以使用this关键字。
super
在子类中可以使用super引用父类成员变量、成员方法以及构造方法。
引用父类成员变量。子类在继承时自动继承父类的所有成员变量,所以可以使用super.成员变量名
来引用父类的成员变量。需要注意的是,当子类中没有声明与父类同名的成员变量时,引用父类的成员可以不使用super;但是当子类中声明了与父类中同名的成员变量时,就必须使用super,否则引用的就是子类的同名成员变量。
调用父类成员方法。因为子类在继承时会继承父类的所有方法,所以可以使用super.成员方法名(参数表)
。在对方法使用super时需要注意的事项和在引用父类成员变量时的相同,即不同名是可以不使用super,同名时如果要调用父类的方法则必须要使用super。
调用父类的构造方法。子类可以通过super来调用父类的构造方法,调用的方式是super(参数表)
,这里的参数表是由父类的构造方法的参数来决定的,并且super()必须是子类构造方法体中的首条语句。
public class Person {
protected String name;
protected int age;
public Person(String myName,int myAge) {
name = myName;
age = myAge;
}
public void print() {
System.out.println("我是一个人");
}
}
public class Student extends Person {
private String grade;
public Student(String myName,int myAge,String myGrade) {
super(myName, myAge); //调用父类的构造方法
grade = myGrade;
}
public void print() {
super.print(); //调用父类的方法print()
System.out.println("我的姓名是:"+name+" 我的年龄是:"+age+" 我的年级是:"+grade);
}
public static void main(String[] args) {
Student zhangsan = new Student("张三",18,"大一");
zhangsan.print();
}
}
this
使用this可以引用当前对象的成员变量、成员方法和构造方法。
访问成员变量。当需要访问成员变量是可以this.成员变量名
。当成员方法中没有与成员变量同名的参数时,this可以省略;但是当有同名的参数时,引用成员变量时其名前的this不能省略。
调用成员方法。通过this调用成员方法的形式是this.成员方法名(参数表)
,这里的this可以省略。
调用构造方法。this(参数表)
。
public class Point {
protected int x;
protected int y;
public Point(int x,int y) { //带参数的构造方法
this.x = x;
this.y = y;
}
public Point() { //不带参数的构造方法
this(5, 5); //调用带参数的构造方法
}
}
public class Circle extends Point {
protected int ridius;
public Circle(int x,int y,int ridius) {
this.x = x;
this.y = y;
this.ridius = ridius;
}
public Circle(int ridius) {
super(); //调用父类的构造方法
this.ridius = ridius;
}
public static void main(String[] args) {
Circle circle1 = new Circle(50, 100, 200);
Circle circle2 = new Circle(200);
}
}
类的多态性
多态性是面向对象的核心特征之一。多态性是指同一名称的方法可以有多种的实现,即有不同的方法体。在程序运行时,系统会根据调用的参数或调用的方法的对象自动选择一个方法执行。多态性是通过方法的重载和覆盖来实现的。
1.方法重载
在一个类中,多个方法具有相同的方法名,但是却具有不同的参数表,这就称为方法的重载。程序在运行时,会根据参数表来决定所执行的方法。例如:
public double area(double a);
public double area(int a,double b);
public double area(double a,int b);
需要注意的是,在重载的方法中的参数表必然不同,具体可以表现在参数的个数不同、参数的类型不同或参数的顺序不同。下面的例子就是错误的示范:
public int volume(int a,int b);
public void volume(int x,int y);
//错误,尽管参数的名字不同,但是参数的个数/类型/顺序完全相同,即具有相同的参数表
2.方法覆盖
覆盖指的是子类重新定义的从父类继承而来的同名方法。即如果父类中的方法不适用与子类,则子类可以自己重新定义该方法。子类中定义的方法与父类的方法具有相同的参数表,但具有不同的方法体。
当程序运行时,系统根据调用方法的对象所属的类决定执行父类中的方法还是子类中的方法。寻找的原则是:首先从对象的所属类开始,寻找匹配方法;如果当前类中没有匹配的方法,则依次在父类,祖先类中寻找匹配方法。
class CCircle{
protected double ridius;
public CCircle(double r){
ridius = r;
}
public void show(){
System.out.println("ridius="+ridius);
}
}
public class CCoin extends CCircle{
private int value;
public CCoin(double r,int v){
super(r);
value = v;
}
public void show(){ //方法的覆盖
System.out.println("value"+value);
}
public static void main(String[] args){
CCircle circle = new CCircle(2.0);
CCoin coin = new CCircle(3.0,5);
circle.show();
coin.show();
}
}
final类和final成员
在Java中的关键字final可以修饰类以及类中的成员变量和成员方法。被final修饰的具体效果:
(1)类。被final修饰的类不能被继承。
(2)成员方法。被final修饰的方法不能被继承。
(3)成员变量。被final修饰的变量的值不能被修改,即该变量是一个常数。