一、类的继承
我们试着想象一下两个类:学生类和大学生类
学生类
属性:姓名、性别、年级、成绩
方法:学习、休息
大学生类
属性:姓名、性别、年级、成绩、专业
方法:学习、休息、实习
我们可以看出来,大学生类的属性和方法包含了学生类的属性与方法,如果我们在定义这两个类的时候将它们的属性和方法全部定义一遍,就显得麻烦同时不精简,由此继承的概念就出来了。
继承:如果A类继承了B类,我们将A类称作B类的子类,B类就是A类的父类。子类拥有父类的全部属性与方法,子类自身也能添加新的方法和属性。继承时需要用到的关键字是extends,具体的使用方法是:
public class 子类名 extends 父类名{};
子类虽然拥有父类全部的属性与方法,但是受限于访问权限,能够调用的方法和属性是限定的。
二、重写与重载
重写:子类继承父类以后,可能之前父类的某个方法已经不能满足子类的条件,这个时候我们就需要重写/覆盖该方法。
重写的两个条件:
1、重写的方法的返回值、方法名、参数个数与类型必须全部一样。
2、重写的方法的访问权限不能比之前的访问权限小,可以扩大。
重载:重载与重写的区别就在于,重载的方法的参数类型或参数数量与之前的方法不一样,返回值是否相同没有关系,但是方法名必须保持一致。其访问权限没有限制。
三、构造方法
类的构造方法可以理解为类的初始化。定义方式为:
public 类名(参数类型 参数名,.....){};
举个例子:
public class Test {
public static void main(String[] args) {
int a = 1;
Circle cir = new Circle(a);
}
}
public class Circle{
public Circle(int a) { //构造方法
System.out.println("circle "+a);
}
}
我在类Circle里写了一个构造方法,参数为一个int型数,当我创建Circle 的对象的时候需要为这个参数赋值,不然会报错。
关于构造方法有几个注意事项:
1、构造方法没有返回值,他在创建对象使用new操作的时候被系统调用,构造方法的名字和类名必须一致。
2、在java中,如果我们没有写构造方法,创建对象时,系统会默认调用一个无参数的构造方法,如果写了构造方法,系统则不会默认调用该构造方法。
3、构造方法可以被重载。我们可以在类中写多个构造方法,但需要保证每个构造方法参数个数或者参数类型不一致。
多个构造方法举例:
public class Test {
public static void main(String[] args) {
int a = 1,b = 2;
Circle cir = new Circle(a);
Circle cir2 = new Circle(a,b);
Circle cir3 = new Circle("圆");
}
}
public class Circle{
public Circle(int a) {
System.out.println("circle "+a);
}
public Circle(int a,int b){
System.out.println("circle "+a+"and "+b);
}
public Circle(String a){
System.out.println("circle "+a);
}
}
我们创建了三个对象,通过不同的赋值,分别系统调用了三个构造方法。
运行结果:
特别注意:创建某个子类对象时,会先调用其父类的构造方法。
public class Test {
public static void main(String[] args) {
int a = 1;
Circle cir = new Circle(a);
}
}
public class Circle extends CC{
public Circle(int a) {
System.out.println("circle "+a);
}
}
public class CC {
public CC(){
System.out.println("I am the father of Circle.");
}
}
运行结果:
主方法中我们创建了Circle对象cir,Circle类继承了类CC,最后的运行结果中显示,我们是先调用了父类CC的构造方法,再调用子类Circle的构造方法。
我们试着将父类CC的构造方法改一下:
public class CC {
public CC(int a){
System.out.println("I am the father of Circle.");
}
}
运行结果:
往父类CC的构造方法中添加了一个参数运行后会报错。我们之前说过,如果一个类没有写构造方法,我们调用它的话系统会给一个默认的无参数的构造方法,但若写了构造方法,这个默认的构造方法则不会调用。这一点父类也一样,我们在创建子类对象的时候会先调用父类的构造方法。而对于子类来说,无论父类有没有参数,都会调用默认的无参数的构造方法,但是因为上面代码中CC父类已经写了一个有参数的构造方法,所以父类中并没有一个默认的无参数的构造方法,编译器便会报错。
上面问题我们可以通过在父类中再写一个无参数的构造方法来解决或者在子类中调用父类的构造方法。
在子类中调用父类的构造方法:
public class Circle extends CC{
public Circle(int a) {
super(a);
System.out.println("circle "+a);
}
}