继承(中)
方法的重写
在继承中,子类会继承父类的定义方法,但有时在子类中需要对继承的方法进行一些修改,也就是对父类的方法进行重写。
在子类中重写的方法需要和父类被重写的方法具有相同的方法名,参数列表和返回值类型,并且在子类重写的方法中不能有比父类方法更严格的访问权限。(一句只能修改方法体和修饰符写这么麻烦,啊这。。。)
public class JiCheng01 { public static void main(String[] args) { Dog dog = new Dog(); dog.shout(); } } class Animal{ //创建父类方法 public void shout(){ System.out.println("发出了狗叫声"); } } class Dog extends Animal{ //对父类方法进行重写 public void shout(){ System.out.println("发出了汪汪叫"); } }
从结果中不难看出,原本应该继承父类的shout方法应该输出“发出了狗叫声”,但是却输出了子类的“发出了汪汪叫”,这就是因为子类对父类的手套、方法进行了重写,从而输出了自己的shout方法的输出语句。
Super关键字
当子类重写过父类的方法之后,子类对象将无法访问父类的方法了。也就是说,当你重写了子类的方法之后,一般我们所写的关于父类的方法的语句将无法继续正确执行。关于这一点,我们可以使用super关键字。
super关键字可以在子类中调用父类的普通属性,方法和成员方法。
(1)super关键子访问父类成员变量和成员方法的格式:
super.成员变量 super.成员方法(参数1,参数2...)public class JiCheng01 { public static void main(String[] args) { Dog dog = new Dog(); dog.shout(); } } class Animal{ public void shout(){ System.out.println("发出了狗叫声"); } } class Dog extends Animal{ public void shout(){ super.shout();//重新调用父类的成员方法 System.out.println("发出了汪汪叫");//对父类的方法进行重写 } }
从图中不难看出,shout语句在子类中已经被重写过了,但是仍然输出了父类方法中的“发出了狗叫声”,这就是因为虽然父类的方法被重写,但是super关键字使子类重新调用了一次父类的shout方法。
(2)使用super关键字调用父类指定的构造方法。
super (参数1,参数2)public class JiCheng02 { public static void main(String[] args) { Dog01 dog001 = new Dog01("二哈",19,"灰白色"); System.out.println(dog001.info());//将类中的方法返回值进行输出 } } class Animal01{ public String name; public int age; //父类的构造方法 public Animal01(String name,int age){ this.name=name; this.age=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; } //父类中创建的一个返回方法info public String info(){ return "姓名:"+this.name+",年龄:"+this.age; } } //定义子类 class Dog01 extends Animal01{ public String color; public Dog01(String name,int age,String color){ super(name, age);//调用父类中的构造方法,将父类的参数传进来 this.color=color; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } //重写父类的info方法 public String info(){ return super.info()+",颜色:"+this.color;//对父类的方法进行扩充 } }
在这里其实我们也可以用前面的方法,直接对name,age,color利用setter方法进行赋值,也就省去了对父类,子类写构造方法的步骤,初学者感觉这参数传来传去有点不稳当,可以利用这种的方法。
public class JiCheng03 { public static void main(String[] args) { Dog02 dog002 =new Dog02(); dog002.setName("柯基"); dog002.setAge(12); dog002.setColor("黄色"); System.out.println(dog002.info()); } } class Animal02{ 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; } public String info(){ return "姓名:"+this.name+",年龄:"+this.age; } } class Dog02 extends Animal02{ private String color; public String getColor() { return color; } public void setColor(String color) { this.color = color; } public String info(){ return super.info()+",颜色:"+this.color; } }
从结果来看,上下两者代码的作用是一样的,但是例题内容重在理解这种关键字的用法,不是说那种简单就用那个,如果只是一昧的使用自己会的东西,那么将永远不会进步,所以说,学习嘛,多多益善。
注意
super()调用父类的构造方法的代码必须位于子类构造方法第一行并且只能出现一次。
所以,super和this不能同时出现,因为两者在调用构造方法时都要求在第一行。
区别 | this | super |
---|---|---|
属性访问 | 访问本类的属性,如果本类中没有属性则前往父类中查找 | 直接访问父类属性 |
方法 | 访问本类的方法,如果本类中没有方法则前往父类中查找 | 直接访问父类方法 |
调用构造 | 调用本类构造,位于构造方法首行 | 调用父类方法,位于子类构造方法首行 |