面向对象的三大特性之(二)继承

一、继承

1、继承的概念:

  继承是类与类的一种关系,如狗类是动物类的继承类
  :Java中的继承是单继承,即一个类只有一个父类

2、继承的好处

  子类拥有父类的所有属性和方法    private修饰的方法和属性无效
  实现代码复用

3、语法规则

  class 子类 extends 父类

public class Animal{
  public int age;
  public String name;
  public void eat(){
    System.out.println("动物具有吃东西的能力");
  }
}

public class Dog extends Animal{
}
//测试类
public class Initial{
  public static void main(String[] args){
    Dog dog = new Dog();
    dog.age = 10;
    dog.name = "mark";
    dog.eat();
  }
}

二、方法重写

1、定义

  如果子类对继承父类的方法不满意,是可以重写父类继承的方法的,当调用方法时会优先调用子类的方法。

2、语法规则:

  • 返回值类型
  • 方法名
  • 参数类型及个数
    都要与父类继承的方法相同,才叫方法的重写
public class Dog extends Animal{
  public void eat(){
    System.out.println("年龄"+age+"狗是可以吃东西的");
  }
}
//测试类
public class InitialClass{
  public static void main(String[] args){
    Dog d = new Dog();
    d.age = 10;
    d.eat();
  }
}

三、继承初始化顺序

  1. 初始化父类再初始子类
  2. 先执行初始化对象中属性,再执行构造方法中的初始化

例如:

//父类
public class Animal{
  public int age = 10;
  public String name;
  public void eat(){
    System.out.println("动物具有吃东西的能力");
  }
  public Animal(){
    System.out.println("Animal类执行了");
    age = 20;
  }
}
//子类
public class Dog extends Animal{
  public Dog(){
    System.out.println("Dog类执行了");
}
//测试类
public class Initial{
  public static void main(String[] args){
    Animal animal = new Animal();
    System.out.println("animal age:"+animal.age);
    Dog dog = new Dog();
    dog.age = 10;
    dog.name = "mark";
    dog.eat();
  }
}

运行结果:

  Animal类执行了
  animal age:20
  Animal类执行了
  Dog类执行了
  动物具有吃东西的能力

  即优先创建父类对象,再创建子类对象


这里写图片描述

四、final关键字

  使用final关键字做标识有”最终的“含义

  final可以修饰方法属性变量。final修饰类,则该类不允许被继承;final修饰方法,则改方法不允许被覆盖(重写);final修饰属性,则该类的属性不会进行隐式的初始化(类的初始化属性必须有值)或在构造方法中赋值(但只能选其一);final修饰变量,则该变量的值只能赋一次值,即变为常量

五、super关键字

  super关键字:在对象的内部使用,可以代表父类对象。

  访问父类的属性 super.age
  访问父类的方法 super.eat()

//父类
public class Animal{
  public int age = 10;
  public String name;
  public void eat(){
    System.out.println("动物具有吃东西的能力");
  }
  public Animal(){
    System.out.println("Animal类执行了");
    //age = 20;
  }
}
//子类
public class Dog extends Animal{
  public int age = 20;
  public void eat(){
    System.out.println("狗具有吃骨头的能力");
  }
  public Dog(){
    //super.();可写可不写,不写的时候隐式地调用父类的构造方法
    System.out.println("Dog类执行了");
  }
  public void method(){
    System.out.println(super.age);
    System.out.println(age);
  }
}
//测试类
public class Initial{
  public static void main(String[] args){
    Dog dog = new Dog();
    dog.method();
  }
}

运行结果:

  Animal类执行了
  Dog类执行了
  10
  20

注意:

  • 子类的构造的过程当中必须调用其父类的构造方法;
  • 如果子类的构造方法中没有显式调用父类的构造方法,则系统默认调用父类无参的构造方法;
  • 如果显式地调用构造方法,必须在子类的构造方法的第一行;
  • 如果子类构造方法中既没有显式调用父类的构造方法,而父类又没有无参的构造方法,则编译出错。

例如:

//父类
public class Animal{
  public int age = 10;
  public String name;
  public void eat(){
    System.out.println("动物具有吃东西的能力");
  }
  /*
  public Animal(){
    System.out.println("Animal类构造方法执行了");
  }
  */
  //定义了一个有参的构造方法,系统就不会再生成无参的构造方法
  public Animal(int age){
    this.age = age;
  }
}
//子类
public class Dog extends Animal{
  public int age = 20;
  public void eat(){
    System.out.println("狗具有吃骨头的能力");
  }
  public Dog(){
    //super.();隐式调用父类的构造方法 !!!!!!!!!!!!!此时会出现编译报错
    System.out.println("Dog类执行了");
  }
  public void method(){
    System.out.println(super.age);
    System.out.println(age);
  }
}
//测试类
public class Initial{
  public static void main(String[] args){
    Dog dog = new Dog();
    dog.method();
  }
}

六、Object类

  Object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object类。
  Object类中的方法,适合所有子类。

1、toString()方法

  在Object类里面定义toString()方法的时候返回的对象的哈希code码(对象地址字符串),可以通过重写toString()方法表示出对象的属性。

//测试类
public class Initial{
  public static void main(String[] args){
    Dog dog = new Dog();
    System.out.println(dog);
  }
}

运行结果:

  Animal类执行了
  Dog类执行了
  com.imooc.Dog@61de33

  Eclipse可以帮助我们自动生成重写的方法。Source->Generate toString()..


这里写图片描述

public class Dog extends Animal{
  public int age = 20;
  public void eat(){
    System.out.println("狗具有吃骨头的能力");
  }
  public Dog(){
    System.out.println("Dog类执行了");
  }
  @Override
  public String toString(){
    return "Dog [age="+age+"]";
  }
}

运行结果:

  Dog类执行了
  Dog [age=20]

2、equals()方法

  比较的是对象的引 用是否指向同一块内存地址
  Dog dog = new dog(),dog不是对象,是对象所在的地址

  一般情况下比较两个对象时比较他的值是否一致,所以要进行重写。

//父类
public class Animal extends Object{
  public int age = 10;
  public String name;
  public void eat(){
    System.out.println("动物具有吃东西的能力");
  }
}
//子类
public class Dog extends Animal{
  public int age = 20;
  public void eat(){
    System.out.println("狗具有吃骨头的能力");
  }
  public void method(){
    eat();
  }
}
//测试类
public class Initial{
  public static void main(String[] args){
    Dog dog = new Dog();
    dog.age = 15;
    Dog dog2 = new Dog();
    dog2.age = 15;
    if(dog.equals(dog2)){
      System.out.println("两个对象是相同的");
    }else{
      System.out.println("两个对象是不相同的");
    }
    if(dog==dog2){
      System.out.println("两个对象是相同的");
    }else{
      System.out.println("两个对象是不相同的");
    }
}

运行结果:

  两个对象是不相同的
  两个对象是不相同的

  ==判断两个基本数据类型的值是否相同;如果判断的是引用的值是否相同,也是比较内存地址。

  所以,如果要相比较两个对象的数据的值师傅相同该怎么办呢?要重写equals()方法。Eclipse在Source->Generate hashcode() and equals()…可以生成。

如下:

@Override
public boolean equals(Object obj){
  if(this == obj)//判断两个引用的地址是否相同
    return true;
  if(obj == null)//如果另外一个地址是空值,就不需要比较了,一定是不相等的
    return false;
  if(getClass()!=obj.getClass())//getClass()可以得到一个类对象。new一个对象的时候,我们得到的是类的对象。类对象描述的是类的代码信息。类的对象关注的是类的属性值的信息,比较见下图。
    return false;
  Dog other = (Dog) obj;
  if(age!=other.age)
    return false;
  return true;
}

\\测试
if(dog.equals(dog2)){
  System.out.println("两个对象是相同的");
  }else{
    System.out.println("两个对象是不相同的");
}

运行结果:

  两个对象是相同的


这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值