一.继承的概念
继承就是字面的理解就好,子继承父的一些特性,并且还可能发生一些“基因突变”,可以包含一些父类没有的方法或者属性。正所谓“青出于蓝而胜于蓝”。
为什么要用继承呢?一方面继承可以向上抽取父类,使代码重用率提高。比如Teacher类和Student类都可以继承person类,另一方面继承可以引出多态,是面向对象的重要特性。
一个例子:
class Person
{
String name;
Person(String name)
{
this.name = name;
System.out.println("Person is Constructed");
}
public void eat()
{
System.out.println("I am a person. I can eat!");
}
}
class Student extends Person
{
String num;//学号
Student(String num,String name)
{
//调用父类构造函数
super(name);
this.num = num;
System.out.println("Student is Constructed");
}
public void study()
{
System.out.println("I am a student. I can sutdy");
}
}
public class InheritsTest1 {
public static void main(String[] args)
{
//创建一个学生对象
Student student1 = new Student("zhang","111");
//调用父类的吃饭方法
student1.eat();
//调用学习方法
student1.study();
}
}
输出的结果如下:
要点:
1.继承的语法 class 子类 extends 父类 {}
2.子类自动拥有父类public 和protected的成员。
3.关于权限问题:
public 外界可以无限制访问
private类外不可访问,只能类内部访问
protected 继承的子类可以访问(在不同的包中也可以)
default即没写权限,默认同一包中的类可以访问。
4.super()调用父类的构造函数,这句话需要在子类构造函数中作为第一句话!!!
二.子类与父类间方法的关系
子类与父类中方法之间有几种关系,第一种就如上面的例子,子类直接继承父类的方法,不进行改变,可以直接调用父类的方法,子类也可以对父类的方法进行扩充,即增加新的方法。如person会eat,student继承了person类,他也会eat,但是又增加了study方法。
后两种关系都发生在子类的方法和父类重名的情况下。
1.子类覆盖父类的方法
例子:
class Person
{
String name;
Person(String name)
{
this.name = name;
System.out.println("Person is Constructed");
}
public void eat()
{
System.out.println("I am a person. I can eat 饭!");
}
}
class Student extends Person
{
String num;//学号
Student(String num,String name)
{
//调用父类构造函数
super(name);
this.num = num;
System.out.println("Student is Constructed");
}
public void eat()
{
System.out.println("I am a student .I can eat 脑白金");
}
public void study()
{
System.out.println("I am a student. I can sutdy");
}
}
public class InheritsTest1 {
public static void main(String[] args)
{
//创建一个学生对象
Student student1 = new Student("zhang","111");
//覆盖了父类的eat饭方法,调用子类的eat脑白金方法
student1.eat();
//调用学习方法
student1.study();
}
}
结果:
可见,子类覆盖了父类的方法。在调用子类的时候,调用eat方法,执行的不是父类的“eat饭”方法,而是子类的"eat脑白金"方法。
2.子类重载父类的方法
class Person
{
String name;
Person(String name)
{
this.name = name;
System.out.println("Person is Constructed");
}
public void eat()
{
System.out.println("I am a person. I can eat 饭!");
}
}
class Student extends Person
{
String num;//学号
Student(String num,String name)
{
//调用父类构造函数
super(name);
this.num = num;
System.out.println("Student is Constructed");
}
public void eat(String food)
{
if (food.equals("naobaijin"))
System.out.println("I am a student .I can eat 脑白金");
}
public void study()
{
System.out.println("I am a student. I can sutdy");
}
}
public class InheritsTest1 {
public static void main(String[] args)
{
//创建一个学生对象
Student student1 = new Student("zhang","111");
//调用父类的eat饭方法
student1.eat();
//调用子类重载的eat脑白金方法
student1.eat("naobaijin");
//调用学习方法
student1.study();
}
}
结果如下:
这样student既可以吃饭,也可以吃脑白金,不同就在与eat方法接受的参数不同,如果是没有参数,那么他就执行父类的eat饭方法,如果有参数,那就执行子类重载的eat脑白金方法,吃脑白金。
要点:
1.子类和父类之间的方法关系有扩充关系(直接调用父类方法或者扩充新方法),覆盖关系(子类与父类方法重名,子类方法覆盖父类方法),重载关系(子类方法与父类方法参数不同,调用时根据参数选择调用哪个方法)
2.覆盖时不能覆盖静态方法,也不能覆盖final方法。
3.覆盖方法的允许访问范围不能小于原方法,覆盖方法抛出的异常不能比原方法多。
4.在子类中可以调用父类的方法,被覆盖的也可以。即用super关键字
例子如下:
class Person1
{
public void eat()
{
System.out.println("I am a person. I can eat 饭!");
}
}
class Student1 extends Person1
{
public void eat()
{
//在子类中可以使用super关键字调用父类的方法,包括被覆盖的方法
super.eat();
System.out.println("I am a student .I can eat 脑白金");
}
public void study()
{
System.out.println("I am a student. I can sutdy");
}
}
public class InheritsTest2 {
public static void main(String[] args)
{
//创建一个学生对象
Student1 student1 = new Student1();
//调用子类的eat方法
student1.eat();
}
}
结果:
三.final关键字与Object类