上次学到封装,在生活中我们可以将教师抽象封装成一个教师类,将学生封装成一个学生类,如以下代码:
class teacher{//教师类
public void eat(){
System.out.println("吃饭");
}
public void work(){
System.out.println("上班");
}
}
class student{//学生类
public void eat(){
System.out.println("吃饭");
}
public void study(){
System.out.println("学习");
}
}
我们可以看到吃饭这个行为教师,学生都具有。是一个重复的代码
在现实生活中,学校还有清洁工,食堂阿姨等等。如果我们在创建这些类的时候都要给他们写上这个方法,代码就有些多了,并且如果某一天他们都不吃饭了,都去吃粉了,我们还需要把每个类的eat()方法全都修改一下。这不利于我们的开发。
所以,java给我们提供了继承的方法,是面向对象的一大特征之一。从上述分析可知,教师和学生都是人类,都需要吃饭。我们可以将这个公共的行为抽离成一个对象。和我们之前封装一个方法来达到重复利用差不多。
只是说java的继承提供了extends关键字,我们不需要自己手动去创建这个公共的对象来调用这些方法,它会自动默认给我们创建这个公共对象,我们把这个公共对象称为父类,继承父类的类称为子类。
将上面的代码修改为
class person{//人类---作为父类
public void eat(){
System.out.println("吃饭");
}
}
class teacher extends person{//教师类----作为子类,可以继承父类的属性和方法
public void test(){
eat();//这个方法来自于父类
}
public void work(){
System.out.println("上班");
}
}
下面来讲讲继承:
**继承的概念**
继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,
还可以在子类中重新定义,以及追加属性和方法
**实现继承的格式**
继承通过extends关键字实现
格式:class 子类 extends 父类 { }
举例:class teacher extends person { }
**继承带来的好处**
提高了代码的复用性(多个类相同的成员可以放到同一个类中)
提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
**继承弊端**
继承让类与类之间产生了关系,类的耦合性增强了,
当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性
**使用场景**
考虑类和类之间的范围关系,比如A类的范围比B类大,并且把B类包含在其中。
我们就可以把A类称为父类,B类称为子类
举例:鱼类可以作为父类,鲫鱼称为子类,草鱼也是他的子类,青蛙类就不是它的子类了。
java还提供了super关键字
super指向父类,this指向本类。除了这一点区别,其他用法全部和this关键字一样。
ta的详细用法就不说了。
之前说子类会自动给我们创建父类对象,那它是怎么实现的呢?
我们都知道每个类都会有一个默认的构造方法,当A类继承了B类时,A类的构造方法里面会默认生成B类的构造方法,并且这个构造方法必须放到第一位,否则就会报错。
之前学到构造方法,当我们自己创建一个有参构造方法时,java就不会给我们创建无参构造方法了。可是我们子类的构造方法里面默认需要用到父类的无参构造方法了,否则就会报错。
我们可以通过super关键字手动去指定父类的构造方法。还是建议不管是什么类有参构造方法和无参构造方法全都写上。
我在这个地方入过一个坑
构造方法是否执行完毕,决定这个对象的成员变量是否存在,所以构造方法还没执行之前不能使用成员变量。当然如果你用static关键字修饰,static修饰的成员变量早就在方法区生成好了,肯定是可以被构造方法使用的
继承中成员方法的访问特
1.通过子类对象访问一个方法
2.子类成员范围找
3.父类成员范围找
4.如果都没有就报错(不考虑父类也有父类的情况)