[Java][华为云Java编程创造营][学习笔记][第二阶段][02_Java面向对象之继承]

举报
John2021 发表于 2021/11/19 19:23:43 2021/11/19
【摘要】 1,类的继承机制 1.1,继承的作用继承的作用:减少重复的冗余的相同属性和方法多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中那么多个类无需再定义这些相同属性和行为,只要继承那个类即可//没有继承public class Student{ //学生姓名 private String name; //学生年龄 private int age; publ...

1,类的继承机制

1.1,继承的作用

  • 继承的作用:减少重复的冗余的相同属性和方法
  • 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中
  • 那么多个类无需再定义这些相同属性和行为,只要继承那个类即可
//没有继承
public class Student
{
    //学生姓名
    private String name;
    //学生年龄
    private int age;

    public void setName(String name)
    {
        this.name = name;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public void eat()
    {
        System.out.println("吃饭");
    }
}

public class Teacher
{
    //老师姓名
    private String name;
    //老师年龄
    private int age;

    public void setName(String name)
    {
        this.name = name;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public void eat()
    {
        System.out.println("吃饭");
    }
}
//有继承
public class Person
{
    //姓名
    private String name;
    //年龄
    private int age;

    public void setName(String name)
    {
        this.name = name;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public void eat()
    {
        System.out.println("吃饭");
    }
}

public class Student extends Person
{

}

public class Teacher extends Person
{

}

1.2,子类继承父类

  • 继承关系是两个类,一个为子类(派生类),一个父类(基类)。
  • 子类继承父类,使用关键字extends来表示。
  • extends的意思是"扩展",子类是对父类的扩展。
  • Java中类只有单继承,没有多继承(一个儿子只有一个直接爸爸,但爸爸可以有多个儿子)
//继承机制
package demo1;

class Person
{
    public void eat()
    {
        System.out.println("吃饭");
    }

    public void sleep()
    {
        System.out.println("睡觉");
    }
}

class Student extends Person
{
}

class Teacher extends Person
{
}

public class ExtendsDemo
{
    public static void main(String[] args)
    {
        Student s = new Student();
        s.eat();
        s.sleep();
        System.out.println("----------");
        Teacher t = new Teacher();
        t.eat();
        t.sleep();
    }
}

1.3,单继承和间接继承

  • Java不支持多继承,只允许一个类直接继承另一个类。
  • 子类只能有一个父类,extends关键字后面只能有一个类名。
//错误示例
class Animal
{
}

class Person
{
}

public class Student extends Person, Animal //报错Class cannot extend multiple classes
{
}

1.4,Object类

  • Object类是Java中所有类的始祖(万物皆对象)。
  • Java中的每一个类都是由它扩展而来,但是并不需要明确写出要继承它。
  • 自然的,所有Java类都拥有了其方法。
//toString()方法
//该方法用来返回对象的字符串表示形式
public class Person
{
    private String name;
    private int age;

    @Override
    public String toString()
    {
        return "Person[" + name + "," + age + "]";
    }

    public static void main(String[] args)
    {
        Person p = new Person();
        p.name = "张三";
        p.age = 20;
        System.out.println(p.toString()); //Person[张三,20]
    }
}
//equals(Object obj)方法
//该方法用来判断两个对象是否相同
//如果没有被重写过,其与==等价
public class PersonOne
{
    public static void main(String[] args)
    {
        PersonOne p1 = new PersonOne();
        PersonOne p2 = new PersonOne();
        System.out.println(p1.equals(p2)); //false
    }
}
//hashCode()方法
//Object类的hashCode方法是返回对象存储地址
public class PersonTwo
{
    public static void main(String[] args)
    {
        PersonTwo p1 = new PersonTwo();
        System.out.println(p1.hashCode()); //460141958

        PersonTwo p2 = new PersonTwo();
        System.out.println(p2.hashCode()); //1163157884
    }
}

1.5,对象向上转型

  • 子类转换成父类,向上转型。
  • 格式:父类名称 对象名称 = new 子类名称();。
  • 含义:把创建的子类对象当做父类看待和使用。
class Person
{
    public void run()
    {
        System.out.println("Person Run");
    }
}

class Student extends Person
{
    public void eat()
    {
        System.out.println("Son eat");
    }
}

public class App
{
    public static void main(String[] args)
    {
        //person(父类引用)可以指向子类
        //向上转型
        Person s2 = new Student();
        s2.run(); //因为已经当做父类使用了,所以可以调用父类的方法

        //但不能调用子类特有的方法
        //s2.eat(); //报错
    }
}

1.6,对象向下转型

  • 父类转换成子类,向下转型
  • 子类 引用=(子类)父类对象
  • 强制类型转换
class Person
{
    public void run()
    {
        System.out.println("Person run");
    }
}

class Student extends Person
{
    public void eat()
    {
        System.out.println("Son eat");
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Person p = new Person();
        //p.eat(); //报错
        //向下转型
        Student s = (Student) p;
        s.eat();
    }
}
//对象向下转型注意
//问题:可能会出现ClassException异常
class Person
{
    public void run()
    {
        System.out.println("Person Run");
    }
}

class Student extends Person
{
    public void eat()
    {
        System.out.println("Son eat");
    }
}

public class Test1
{
    public static void main(String[] args)
    {
        Person p = new Person();
        Student s = (Student) p;
        s.eat();
    }
}

2,super关键字

2.1,super访问构造函数

2.1.1,super在继承构造函数中定义和作用

  • 在继承中子类的构造函数必须依赖父类提供的构造函数。
  • super(参数列表)访问父类的构造函数。
  • super调用父类的构造函数,必须在构造函数的第一行。
class Person
{
    public Person()
    {

    }
}

class Student extends Person
{
    Student()
    {
        super();
    }
}
  • 在继承中子类的构造函数必须依赖父类提供的构造函数
class Person
{
    private String name;
    private int age;

    public Person(String name, int age)
    {

    }
}

class Student extends Person
{
    Student()
    {
        //1,如果父类提供的只有有参数的构造函数,子类的构造必须依赖父类提供的现有构造函数。
        //2,super(参数列表)去访问父类提供的构造函数,必须明确写出参数。
        //3,super必须在第一行
        super("Huawei", 10);
    }
}

2.2,super访问父类的属性

  • 在子类的方法或构造器中,通过使用super属性。
  • 特殊情况:当子类和父类中定义了同名的属性时,想要调用父类中声明的属性,就要通过super.属性的方式来表明调用的是父类中声明的属性。
class Person
{
    //身份证号码
    int id = 1001;
}

class Student extends Person
{
    //学生证号码
    int id = 80;

    public void show()
    {
        System.out.println("身份证号码是:" + super.id + ",学生证号码是:" + id);
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Student s = new Student();
        s.show();  //身份证号码是:1001,学生证号码是:80
    }
}

2.3,super访问父类的方法

  • 在子类的方法或构造器中,通过使用super.方法名
class Person
{
    public void eat()
    {
        System.out.println("Person eat");
    }
}

public class Student extends Person
{
    public Student()
    {
        //访问父类的方法
        super.eat();
    }

    public static void main(String[] args)
    {
        Student student = new Student();
    }
}

2.4,super和this区别

  • super()调用父类的构造函数,必须在构造函数的第一行。
  • this()调用本类的构造函数,必须在构造函数的第一行。
  • super()和this()不能同时调用构造函数。
  • 代表的对象不同(this:本身调用者这个对象;super:代表父类对象的引用)。
  • 前置(this:没有继承也可以使用;super:只能在继承条件下才能使用)。
  • 构造方法(this():本类的构造;super():父类的构造)

3,final关键字

3.1,final修饰变量

  • final关键字修饰的变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改。
  • final关键字修饰的变量,如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象
  • final修饰的变量都是常量。
  • final可以修饰局部变量。
public class Test
{
    final int a = 10;
    final String s = new String("123");

    public Test()
    {
        //this.a++;  //报错:Cannot assign a value to final variable 'a'
        //s = new String("456");  //报错:Cannot assign a value to final variable 's'
    }
}

3.2,final修饰方法

  • final修饰的成员方法不能被子类重写。
//当父类的方法为final时,子类不能与父类有方法名、参数类型、参数个数及参数顺序都一样的方法。
class Person
{
    final void show()
    {
        System.out.println("Person:show");
    }
}

class Student extends Person
{
    //final void show()  //报错:'show()' cannot override 'show()' in 'demo13.Person'; overridden method is final
    {
        System.out.println("Student:show");
    }
}
//父类方法为private修饰符的final方法
class Person
{
    private final void show()
    {
        System.out.println("Person:show");
    }
}

class Student extends Person
{
    public final void show()
    {
        System.out.println("Student:show");
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Person person = new Person();
        Student student = new Student();
        //private 的方法仅本类可见,该方法不可见
        //person.show(); //不可见
        student.show(); //Student:show
    }
}

3.3,final修饰类

  • final修饰的类不能被子类继承
  • final类中的成员方法也默认为final
  • final类中的变量值是可以改变的
public final class FinalClass
{
    int i = 1;
    static int a = 10;

    void test()
    {
        System.out.println("FinalClass:test");
    }

    public static void main(String[] args)
    {
        FinalClass finalClass = new FinalClass();
        System.out.println("finalClass.i = " + finalClass.i);
        finalClass.i = 2;
        System.out.println("finalClass.i = " + finalClass.i);
        System.out.println("finalClass.a = " + a);
        a = 2;
        System.out.println("finalClass.a = " + a);
    }
}

//final修饰的类不能被子类继承
//class ChildClass extends FinalClass  //Cannot inherit from final 'demo15.FinalClass'
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。