1.继承 extends
1.为什么使用继承:
在程序的编写过程中,可能出现多个重复内容,这些重复类容需要提取出来
2.什么是继承
将多个类中相同属性和行为提取出来形成一个父类,多个类去继承这个类
3.好处:提高代码复用率,便于功能的扩展
4.格式:
//父类
public class Animal {
}
//子类
public class Cat extends Animal{
}
如果我们没有显式的声明一个类的父类的话,则此类继承于 java.lang.Object 类
Animal类默认继承了java.lang.Object类
5.特点:
子类拥有父类非 private 的属性、方法。
父类提供getter和setter方法供子类使用私有属性
//父类
public class Animal{
//私有化属性
private String name;
private int age = 10;
//非私有化属性
public String sex;
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 void eat(String food){
System.out.println(age+"岁的"+sex+"性"+name+"在吃:"+food);
}
//私有化方法
private void fly(){
System.out.println("飞翔");
}
}
//子类
public class Dog extends Animal{
public void eat(String food){
//调用父类属性
super.sex = "男";
//不能调用父类的私有属性
// super.name = "狗";
//通过调用父类setter方法给name赋值
super.setName("狗");
//通过父类getter方法获取age的值
super.getAge(); // age = 10
//调用父类的eat方法
super.eat(food);
//不能调用父类中的私有方法
// super.fly();
}
}
-
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展
//父类
public class Animal{
private String name;
private int age;
public String sex;
public void eat(String food){
System.out.println(age+"岁的"+sex+"性"+name+"在吃:"+food);
}
}
//子类
public class Cat extends Animal{
//子类特有的属性
private String color;
//子类特有的方法
public void speak(){
System.out.println("喵喵喵");
}
}
- 只能单继承,支持多重继承
//错误写法,只能继承一个父类
public class Cat extends Animal extends Dog{
}
//多重继承
public class Cat extends Animal{
}
public class Animal extends Biology{
}
-
子类不继承父类的构造方法,只能调用
//父类
public class Animal{
private String name;
private int age;
public String sex;
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 Animal() {
System.out.println("已自动调用父类无参构造方法");
}
//有参构造方法
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void show(){
System.out.println("姓名:"+name+"年龄:"+age);
}
}
//子类
public class Cat extends Animal {
//无参构造方法
public Cat(){
//系统会自动调用父类的无参构造方法
}
//有参构造方法
public Cat(String name,int age){
//用super调用父类的有参构造方法
super(name,age);
}
}
//测试类
public class Demo {
public static void main(String[] args) {
Cat cat = new Cat(); //自动调用父类的无参构造方法
Cat cat1 = new Cat("虹猫",18);
cat1.show();
}
}
//结果
已自动调用父类无参构造方法
姓名:虹猫 年龄:18
2.方法的重写
什么是方法的重写:
在继承的情况下,子类重写父类方法
原则:
方法名相同,参数列表相同,返回值类型必须是父类返回值的派生类,访问权限不得严于父类
@Override,表示该方法一定是重写父类的方法
//父类
public class Animal{
public void eat(String food){
System.out.println(age+"岁的"+sex+"性"+name+"在吃:"+food);
}
}
//子类
public class Cat extends Animal {
@Override //表示该方法一定是重写父类的方法
public void eat(String food){
}
//子类重写方法的权限比父类权限小,会报错
// protected void eat(String food){
// }
}
//父类
public class Animal{
public void eat(String food){
System.out.println("吃"+food);
}
}
//子类1
public class Cat extends Animal {
@Override //表示该方法一定是重写父类的方法
public void eat(String food){
System.out.println("猫在吃"+food);
}
}
//子类2
public class Dog extends Animal{
//没有重写eat方法
}
//测试类
Cat cat = new Cat();
cat.eat("鱼");
//结果为:猫在吃鱼
Dog dog = new Dog();
dog.eat("骨头");
//结果为:吃骨头
结论:若子类若重写了eat方法,调用时,则调用子类中的eat方法
若子类没有重写eat方法,则调用父类中的eat方法
3.super关键字和this关键字
Super关键字表示自己的父类对象
this关键字表示自身对象
//父类
public class Animal{
public String name;
public Animal(String name){
this.name = name; //this.age表示当前对象Animal的age
}
public void speak(){
}
}
//子类
public class Cat extends Animal {
public int age;
public Cat(String name,int age){
//调用父类中的某个构造方法时,必须写在第一行
super(name);
this.age = age; //this.age表示当前对象Cat的age
}
public void show(){
System.out.println("hhh");
}
public void eat(){
//调用父类中的方法
super.speak();
//调用本类中的方法
this.show();
}
}
所有子类构造方法中如果没有显式地调用父类的构造方法,都会默认调用父类的无参构造方法,若此时父类没有无参构造方法,会报错。
//父类
public class Animal{
public String name;
public Animal(String name){
this.name = name;
}
//父类的无参构造方法
public Animal(){
System.out.println("哈哈哈");
}
}
//子类
public class Cat extends Animal {
public int age;
//两个子类构造方法均没有显式地调用父类构造方法
public Cat(String name,int age){
//super();默认调用父类无参构造方法,不显示
}
public Cat(){
//super();默认调用父类无参构造方法,不显示
}
}
public class Demo {
public static void main(String[] args) {
Cat cat = new Cat();
Cat cat1 = new Cat("小白",12);
}
}
结果为:
哈哈哈
哈哈哈
均调用了父类的无参构造方法
在构造方法中,无论是super调用父类的构造方法,还是this调用本类的构造方法,都必须出现在第一行,在一个构造方法中不能同时调用父类和子类的构造方法。
//父类
public class Animal{
public String name;
public Animal(String name){
this.name = name;
}
public Animal(){}
}
//子类
public class Cat extends Animal {
public int age;
public Cat(String name,int age){
}
public Cat(){
//this和super只能2选1
this("张三",18);
super(); //报错
}
}
构造方法中,this调用构造方法时,只能调用其他构造方法,不能自己调用自己
public class Cat extends Animal {
public int age;
public Cat(String name,int age){
super.name = name;
this.age = age;
}
public Cat(){
// this(); 不能调用自己
this("哈哈", 15);//可以调用其他构造方法
}
4.fianl关键字
final表示最终的,不可修改的
final修饰类: 表示为该类不可被继承
final修饰方法:表示该方法不可被重写
final修饰变量:表示该变量不可改变,就是常量
//父类
//public final class Animal{ 用final修饰类时,该类无法被继承
public class Animal{
public final String name="小白";
public Animal(String name){
// this.name = name; //final修饰的变量为常量,运行过程中不能再次对他赋值
}
public Animal(){
System.out.println("哈哈哈");
}
//final修饰的方法,无法被子类继承
public final void show(String name){
}
}
//子类
public class Cat extends Animal {
public int age;
public Cat(String name,int age){
// super.name = name; //final修饰的变量为常量,运行过程中不能再次对他赋值
this.age = age;
}
public Cat(){
}
//无法重写父类被final修饰的方法
// @Override
// public void show(String name){
//
// }
}