定义:
面向对象编程支持从已经存在的类中定义新的类,称为继承。
特点:
- 利于代码复用,缩短开发周期
- 是一种类与类的关系
- 继承中可以定义一个通用的类称为父类,之后继承该类为一个特定的类称为子类
父类:基类
子类:派生类
实现继承:
使用extends实现封装
- 编写父类:
class Animal{
//公共的属性和方法
}
- 编写子类,继承父类:
class Dog extends Animal{
//子类特有的属性和方法,一个字类只能继承一个父类
}
实例:
先创建一个父类:
package Animal;
public class animal {
private String name;// 昵称
protected int month;// 月份
String species;// 品种
//父类的构造方法不允许被继承、不允许被重写
public Animal(){
}
public String getName() {
//this.temp=22;
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
// 吃东西
public void eat() {
System.out.println(this.getName() + "在吃东西");
}
public void eat(String name) {
System.out.println(name + "在吃东西");
}
public boolean equals(Object obj){
//if(obj==null)
//return false;
animal temp=(animal)obj;
if(this.getName().equals(temp.getName()) && (this.getMonth()==temp.getMonth()))
return true;
else
return false;
}
public boolean equals(animal obj){
if(obj==null)
return false;
if(this.getName().equals(obj.getName()) && (this.getMonth()==obj.getMonth()))
return true;
else
return false;
}
}
再创建两个子类:
package Animal;
public class Cat extends animal{
private double weight;//体重
public Cat(){
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
//跑动的方法
public void run(){
//super();
//eat();
//Animal();
System.out.println(this.getName()+"是一只"+this.getSpecies()+",它在快乐的奔跑");
}
}
package Animal;
public class Dog extends animal {
private String sex;//性别
public Dog(){
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
//睡觉的方法
public void sleep(){
super.eat();//调用的哪个eat();
super.species="犬科";
System.out.println(this.getName()+"现在"+this.getMonth()+"个月大,它在睡觉~~");
}
}
接下来创建测试类:
package Animal;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Cat one=new Cat();
one.setName("花花");
one.setSpecies("中华田园猫");
one.eat();
one.run();
System.out.println("===================");
Dog two=new Dog();
two.setName("妞妞");
two.setMonth(1);
two.eat();
two.sleep();
System.out.println("===================");
two.eat("凡凡");
}
}
子类构造默认调用父类无参构造
注意:如果采用挎包测试,在测试类中需要导包
运行结果为:
方法重写:
要重写一个方法,需要在子类中使用和父类一样的签名来对该方法进行定义。
子类从父类中继承方法。有时子类需要修改父类定义的方法的实现,着称为方法重写。
语法规则:
在有继承关系的子类中,返回值类型;方法名;参数类型、顺序、个数都要与父类继承的方法相同
静态方法和最终方法不能被重写;但静态方法在子类中可以通过隐藏父类方法的方式重新实现。 重写方法的返回值应该与父类方法相同或者是父类方法返回值的子类; 重写方法访问权限必须大于等于父类方法。
访问修饰符的分类及作用
private:只允许在本类中进行访问
public:允许在任意位置访问
protected:允许在当前类、同包子类、跨包子类调用,跨包非子类不允许
默认:允许在当前类、同包子类和非子类调用;跨包子类、非子类不允许调用。
子类重写父类中的方法时,访问修饰符的访问范围需要大于等于父类的
super关键字
关键字super指代父类,可以用于调用父类中的普通方法和构造方法。
关键字super可用于两种途径:
- 调用父类的构造方法
- 调用父类的普通方法
1.调用父类的构造方法:
构造方法用于构建一个类的实例。不同于属性和普通方法,父类的构造方法不会被子类继承。它们只能使用关键字super从子类的构造方法中调用。
调用父类构造方法的语法:
super()或则super(arguments);
/*语句super()是调用父类的无参构造方法,
而语句super(arguments)调用与arguments匹配的父类的构造方法。
语句super()或super(arguments)必须出现在子类构造方法的第一行,
这是显示调用父类构造方法的唯一方式。
*/
警示: 要调用父类的构造方法就必须使用关键字super,而且这个调用必须是构造方法的第一句。 在子类中调用父类的构造方法会有语法错误。
2.调用父类的普通方法:
语法:super.方法名(参数)
super代表父类引用:
- 访问父类成员方法:
super.print();
- 访问父类属性:
super.name;
- 访问父类构造方法:
super();
有关super的注意事项:
- 子类的构造的过程中必须调用其父类的构造方法
- 如果子类的构造方法中没有显示调用父类的构造方法,则系统会默认调用父类无参的构造方法
- 如果子类构造方法中既没有显示调用父类的构造方法,而父类又没有无参的构造方法,则编译出错
- 使用super调用父类指定构造方法,必须放在子类构造方法的第一行
this关键字和super关键字的区别:
1. this:当前类对象的引用
- 访问当前类的成员方法
- 访问当前类的成员属性
- 访问当前类的构造方法
- 不能在静态方法中使用
2.super:父类对象的引用
- 访问父类的成员方法
- 访问父类的成员属性
- 访问父类的构造方法
- 不能在静态方法中使用
所以:构造方法调用时,this和super方法不能同时出现
总结
概念:
- 一种类与类之间的关系
- 使用已存在的类的定义作为基础建立新类
- 新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。
特点:
- 提高代码复用率
- 缩短开发周期
语法:
- 使用extends实现继承
- 单一继承,只能有一个父类
继承后的初始化顺序:
父类静态成员——>子类静态成员——>父类对象构造——>子类对象构造