继承的定义和使用
在现实生活中,我们存在继承,子女继承父母的特性。之所以会存在继承,那是因为我们想要在现有的基础上多出更多的功能。所以,继承也就是在现有的基础上进行功能的扩充。
下面看一看没有继承和有继承代码块的区别:
没有继承:
class Person{
private String name;
private int age;
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age=age;
}
}
class Student{
private String name;
private int age;
private school;
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age=age;
}
public String getSchool(){
return school;
}
public void setSchool(String school){
this.school=school;
}
}
有继承:
class Person{
private String name;
private int age;
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age=age;
}
}
class Student extends Person{//定义一个子类并且继承Person类
}
public class Jintai1{
public static void main(String[] args){
Student t1=new Student();
t1.setName("stenve");
t1.setage(16);
System.out.println("姓名"+t1.getName()+"年龄"+t1.getAge());//继承完以后原来的这两个属性都是私有的,所以我们需要通过它
//的方法来访问这两个属性。
}
}
从以上的代码我们可以看出来,没有继承,我们的代码重复量特别的大,这样的话其实就在浪费资源;但是如果我们用继承来实现的话,原有的功能我们不需要任何代码,只需要一个extends的关键字就可以将以前的所有属性结构都继承过来。
1.继承的实现
继承的实现只需要通过extends关键字:class 子类 extends 父类
下面看一个继承的小栗子:
class Person{
private String name;
private int age;
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age=age;
}
}
class Student extends Person{//定义一个子类并且继承Person类
}
从上面的代码我们可以看出,通过继承以后,子类可以直接操作父类的属性、方法,但是需要知道权限的问题。对于继承,子类最低也维持和父类相同的功能,但也可以扩充属性和方法。
栗子:子类进行功能的扩充
class Person{
private String name;
private int age;
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age=age;
}
}
class Student extends Person{//定义一个子类并且继承Person类,并且扩充其功能
private String school;
public String getSchool(){
return school;
}
public void setSchool(String school){
this.school=school;
}
}
public class Jicheng1{
public static void main(String[] args){
Student t1=new Student();
t1.setName("stenve");
t1.setAge(16);
t1.setSchool("三");//私有属性不可以通过t1.school来访问
System.out.println("姓名"+t1.getName()+"年龄"+t1.getAge()+"学校"+t1.getSchool());//继承完以后原来的这两个属性都是私有的,所以我们需要通过它
//的方法来访问这两个属性。
}
}
2.继承的限制
子类对象在进行实例化之前会先实例化父类的对象。所以会先默认的调用父类的构造方法以后再调用子类的构造方法。
栗子:子类对象的创建
(1)父类的构造函数为无参构造时
class Person{
private String name;
private int age;
public Person(){
System.out.println("这是父类的无参构造");
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age=age;
}
}
class Student extends Person{//定义一个子类并且继承Person类,并且扩充其功能
private String school;
public Student(){
super();
System.out.println("这是子类的无参构造");
}
public String getSchool(){
return school;
}
public void setSchool(String school){
this.school=school;
}
}
public class Jicheng1{
public static void main(String[] args){
Student t1=new Student();
t1.setName("stenve");
t1.setAge(16);
t1.setSchool("三");//私有属性不可以通过t1.school来访问
System.out.println("姓名"+t1.getName()+"年龄"+t1.getAge()+"学校"+t1.getSchool());//继承完以后原来的这两个属性都是私有的,所以我们需要通过它
//的方法来访问这两个属性。
}
}
由上面的运行结果我们可以看到,当父类是无参数构造函数时(即为默认构造函数时)子类在创建对象的时候,会在自己的构造方法中自动默认的调用super();它表示父类的无参构造函数。
(2)父类的构造函数为有参构造时
a.调用含有一个参数的构造函数
// class Person{
// private String name;
// private int age;
// public Person(){
// System.out.println("这是父类的无参构造");
// }
// public String getName(){
// return name;
// }
// public void setName(String name){
// this.name=name;
// }
// public int getAge(){
// return age;
// }
// public void setAge(int age){
// this.age=age;
// }
// }
// class Student extends Person{//定义一个子类并且继承Person类,并且扩充其功能
// private String school;
// public Student(){
// super();
// System.out.println("这是子类的无参构造");
// }
// public String getSchool(){
// return school;
// }
// public void setSchool(String school){
// this.school=school;
// }
// }
// public class Jicheng1{
// public static void main(String[] args){
// Student t1=new Student();
// t1.setName("stenve");
// t1.setAge(16);
// t1.setSchool("三");//私有属性不可以通过t1.school来访问
// System.out.println("姓名"+t1.getName()+"年龄"+t1.getAge()+"学校"+t1.getSchool());//继承完以后原来的这两个属性都是私有的,所以我们需要通过它
// //的方法来访问这两个属性。
// }
// }
b.调用含有两个参数的构造函数
class Person{
private String name;
private int age;
public Person(String name) {
this.name=name;
System.out.println("这是父类的含有一个参数的构造");
}
public Person(String name,int age){
this.name=name;
this.age=age;
System.out.println("这是父类的含有两个参数的构造函数");
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
class Student extends Person{//定义一个子类并且继承Person类,并且扩充其功能
private String school;
// public Student(String name,int age,String school){
// //super(name,age);//指定调用的到底是父类的哪个构造函数
// this.school=school;
// System.out.println("这是子类的构造");
// }
public Student(String name,String school){
//super(name,age);//指定调用的到底是父类的哪个构造函数
super(name);
this.school=school;
System.out.println("这是子类的构造函数");
}
public String getSchool(){
return school;
}
}
public class Jicheng1{
public static void main(String[] args){
Student t1=new Student("stenve","三");
//t1.setSchool("三");//私有属性不可以通过t1.school来访问
System.out.println("姓名"+t1.getName()+"年龄"+t1.getAge()+"学校"+t1.getSchool());//继承完以后原来的这两个属性都是私有的,所以我们需要通过它
//的方法来访问这两个属性。
}
}
由上面的运行结果我们可以看到,当父类是含参数构造函数时,子类在创建对象的时候,需要自己在构造方法中表明到底调用的是父类的那个构造函数,需要调用super(参数1,参数2……);它表示父类的具体的一个含参构造函数。
3.在java中只可以单继承,不能多继承
一个子类只能继承一个父类:
栗子:
class A{
}
class B{
}
class C extends A,B{
}
这是错误的。
多层继承:多继承不可以,我们就采用多层继承的当时来实现多继承
栗子:
class A{}
class B extends A{}
class C extends B{}
重点来啦:在继承的时候,子类会将父类的所有结构(私有属性、私有方法、构造方法、普通方法等等),但是需要注意的是在子类中对于父类的私有属性不可以直接访问,需要通过父类的一些公有的方法来操作。
显示继承:对于公有的属性
如果是显示继承,那么继承以后可以直接访问父类的属性
隐式继承:对于私有的属性
如果是隐式继承那么继承以后必须通过公有的方法才可以访问私有的属性
小小的总结:本节需要掌握的知识
(1)继承的语法、继承的目的
(2)继承以后在1子类创建对象的时候调用父类的构造方法的两种2情况
(3)对于继承以后的属性的访问权限