zoukankan      html  css  js  c++  java
  • 36.Java对象的特征之一_继承_super_instanceof

    继承

    1.1    类和类之间的常见关系。

       1:既然继承是描述类和类之间的关系,就需要先来了解类和类之间的常见关系

    1.1.1  现实生活的整体与部分

    举例说明

    1:现实生活

       1:学生   是人 

       2:狗     是动物

       3:球队 包含 球员 整体与部分的关系,部分可以删除和增加

       4:笔记本包含 cpu 整体与部分的关系,部分不可以删除和增加

       5:航母编队 包含(航母 护卫舰 驱逐舰 舰载机 核潜艇)

    1.1.2   java中的类与类关系

    java中的类关系

    1:is a 关系 (学生是人)

    2:has a 整体与部分

    class Person{
        String name;
        int age;
        Address add;
        
        Person(){
            
        }
        Person(String name,int age,Address add){
            
            this.name=name;
            this.age=age;
            this.add=add;
            
        }
        
        void speak(){
            System.out.println("姓名:"+name+" 年龄:"+age+" "+add.print());
        }
    }
    class Address{
        String country;
        String city;
        String street;
        
        Address(){
        
        }
        Address(String country,String city,String street){
            this.country=country;
            this.city=city;
            this.street=street;
        }
        
        String print(){
            return "地址:"+country+" "+"城市:"+city+"  街道;"+street;
        }
    }
    class Demo3{
    
        public static void main(String[] args){
            
            Address add=new Address("中国","广州","棠东东路");
            Person p=new Person("jack",27,add);
            p.speak();
            
            
            System.out.println();
             }
    }

    1.2   继承

       1:描述一个学生类

          1:姓名年龄学号属性,学习的方法

       2:描述一个工人类

          1:姓名年龄工号属性,工作的方法

       3:描述一个人类

          1:姓名年龄属性,说话的方法。

    4:发现学生类和人类天生有着联系,学生和工人都是人。所以人有的属性和行为学生和工人都会有。出现类代码重复

    class Person {
        String name;
        int age;
    
        // 静态变量(类变量)对象和对象之间的代码重复使用静态变量
        static String country = "CN";
    
        Person() {
    
        }
    
        void speak() {
            System.out.println(name + ":哈哈,我是人!!!");
        }
    
    }
    
    // 让学生类和人类产生关系,发现学生is a 人,就可以使用继承
    class Student {
    
        String name;
        int age;
    
        Student() {
    
        }
    
        void study() {
            System.out.println("姓名:" + name + "年纪:" + age + ":好好学习");
        }
    }
    
    class Worker {
        String name;
        int age;
    
        void work() {
            System.out.println(name + ":好好工作,好好挣钱。");
        }
    
    }
    
    class Demo1 {
    
        public static void main(String[] args) {
            Student s = new Student();
            s.name = "jack";
            s.age = 20;
            s.study();
    
            Worker w = new Worker();
            w.name = "rose";
    
            w.work();
        }
    }

    5:问题:

          1:如果没有继承,出现类和类的关系无法描述

          2:如果没有继承,类和类之间有关系会出现类和类的描述代码的重复。

    1.3    继承特点

       1:描述类和类之间的关系

       2:降低类和类之间的重复代码

    1:降低对象和对象之间的代码重复使用静态变量

       2:降低类和类之间的代码重复使用就继承

      

    1.4    extends关键字

    继承使用extends关键字实现

    1:发现学生是人,工人是人。显然属于is a 的关系,is a就是继承。

    2:谁继承谁?

       学生继承人,发现学生里的成员变量,姓名和年龄,人里边也都进行了定义。有重   复代码将学生类的重复代码注释掉,创建学生类对象,仍然可以获取到注释的成员。这就是因为继承的关系,学生类(子类)继承了人类(父类)的部分

    class Person {
        String name;
        int age;
    
        // 静态变量(类变量)对象和对象之间的代码重复使用静态变量
        static String country = "CN";
    
        Person() {
    
        }
    
        void speak() {
            System.out.println(name + ":哈哈,我是人!!!");
        }
    
    }
    
    // 让学生类和人类产生关系,发现学生is a 人,就可以使用继承
    class Student extends Person {
    
        Student() {
    
        }
    
        void study() {
            System.out.println("姓名:" + name + "年纪:" + age + ":好好学习");
        }
    }
    
    class Worker extends Person {
    
        void work() {
            System.out.println(name + ":好好工作,好好挣钱。");
        }
    
    }
    
    class Demo1 {
    
        public static void main(String[] args) {
            Student stu = new Student();
            stu.name = "jack";
            stu.age = 20;
            stu.study();
            stu.speak();
            System.out.println(stu.country);
            System.out.println(Student.country);
    
            Worker worker = new Worker();
            worker.name = "rose";
            System.out.println(worker.country);
            worker.work();
            worker.speak();
    
            System.out.println();
        }
    }

    继承细节;     

       1:类名的设定,被继承的类称之为父类(基类),继承的类称之为子类

       2:子类并不能继承父类中所有的成员

    1:父类定义完整的成员静态成员,非静态,构造方法。静态变量和静态方

    法都可以通过子类名.父类静态成员的形式调用成功。

          2:所有的私有成员不能继承,private修饰的成员。

          3:构造函数不能被继承

     

       3:如何使用继承

    1:不要为了使用继承而继承。工人和学生都有共性的成员,不要为了节省代码,让工人继承学生。

     

    /*
    如何使用继承:验证是否有 is  a 的关系
     例如:学生是人, 小狗是动物
     注意:不要为了使用某些功能而继承,java只支持单继承
     */
    class DK {
    
        void Ip4S() {
            System.out.println("好玩");
        }
    }
    
    class BGir extends DK {
    
    }
    
    class Demo {
    
        public static void main(String[] args) {
    
            new BGir().Ip4S();
    
        }
    }

    1.5super关键字

       1:定义Father(父类)

          1:成员变量int x=1;

          2:构造方法无参的和有参的,有输出语句

       2:定义Sonextends Father

          1:成员变量int y=1;

          2:构造方法无参和有参的。有输出语句

          1this.y=y+x;

       3:创建Son类对象

          Son son=new Son(3);

          System.out.println(son.y); //4

    class Father {
        int x = 1;
    
        Father() {
            System.out.println("这是父类无参构造");
        }
    
        Father(int x) {
    
            this.x = x;
            System.out.println("这是父类有参构造");
        }
    
        void speak() {
            System.out.println("我是父亲");
        }                  
    }
    
    class Son extends Father {
        int y = 1;
    
        Son() {
            System.out.println("这是子类的无参构造");
        }
    
        Son(int y) {
    
            this.y = y + x;
            System.out.println("这是子类的有参构造");
        }
    
        void run() {
            super.speak(); // 访问父类的函数
            System.out.println("我是儿子");
        }
    }
    
    class Demo6 {
    
        public static void main(String[] args) {
            Son s = new Son(3);
            System.out.println(s.y);// 4
        }
    }

    4:子类对象为什么可以访问父类的成员。

          1this.y=y+x;有一个隐式的super super.x

     

       5super关键字作用

          1:主要存在于子类方法中,用于指向子类对象中父类对象。

          2:访问父类的属性

          3:访问父类的函数

          4:访问父类的构造函数

       6super注意

    thissuper很像,this指向的是当前对象的调用,super指向的是当前调用对象的父类。Demo类被加载,执行main方法,Son.class加载,发现有父类Father类,于是Father类也加载进内存。类加载完毕,创建对象,父类的构造方法会被调用(默认自动无参),然后执行子类相应构造创建了一个子类对象,该子类对象还包含了一个父类对象。该父类对象在子类对象内部。this super只能在有对象的前提下使用,不能在静态上下文使用。

    2:子类的构造函数默认第一行会默认调用父类无参的构造函数,隐式语句

    super();

              1:父类无参构造函数不存在,编译报错。

    Son(int y) {
            //super();隐式语句
            this.y = y + x;
            System.out.println("这是子类的有参构造");
        }

    3:子类显式调用父类构造函数

    在子类构造函数第一行通过super关键字调用父类任何构造函数。如果显式调用父类构造函数,编译器自动添加的调用父类无参数的构造就消失。构造函数间的调用只能放在第一行,只能调用一次。super() this()不能同时存在构造函数第一行。

    Son(int y) {
            super(y);// 子类显式调用父类构造函数
            this.y = y + x;
            System.out.println("这是子类的有参构造");
        }
    
    Son(int y) {
            this();  //不能同时存在构造函数第一行  
            super(y);
            this.y = y + x;
            System.out.println("这是子类的有参构造");
        }

    4super思考

    如果开发者自定义了一个类,没有显示的进行类的继承,那么该类中成员函数是否可以使用super关健健字?可以使用,继承了Object类,Object类是所有类的父类。

    class Demo7 {
        public  void print(){
            System.out.println(super.toString());
        }
        public static void main(String[] args){
            new Demo7().print();
            System.out.println();
             }
    }

    7:重写(Override

    1:定义Father

       1:姓名,吃饭方法,吃窝窝头。

       2:定义Son类,继承Father

          1Son类中不定义任何成员,子类创建对象,仍然可以调用吃饭的方法。

          2:父类的吃饭的方法,Son不愿吃。Son自己定义了吃饭的方法。

    1:此时父类中有一个吃饭的方法,子类中有2个吃饭的方法,一模一样,只是方法体不一样。

              2:一个类中两个函数一模一样,是不允许的。

                 1:编译运行,执行了子类的方法。

                 2:使用父类的方法,在子类方法中,使用super.父类方法名。

    class Father {
        String name;
    
        void eat() {
            System.out.println("吃窝窝");
        }
    }
    
    class Son extends Father {
    
        public void eat() { // 继承可以使得子类增强父类的方法
            System.out.println("来俩小菜");
            System.out.println("来两杯");
            System.out.println("吃香喝辣");
                System.out.println("来一根");
        }
    }
    
    class Demo8 {
    
        public static void main(String[] args) {
            Son s = new Son();
            //执行子类的方法
            s.eat();
    
        }
    }

    3:该现象就叫做重写(覆盖 override)

    1在继承中,子类可以定义和父类相同的名称且参数列表一致的函数,将这种函数

    称之为函数的重写.

    4:前提

       1:必须要有继承关系

    5:特点

    1:当子类重写了父类的函数,那么子类的对象如果调用该函数,一定调用的是重写过后的函数。

          可以通过super关键字进行父类的重写函数的调用。

       2继承可以使得子类增强父类的方法

    6:细节

       1函数名必须相同

       2:参数列表必须相同

    3子类重写父类的函数的时候,函数的访问权限必须大于等于父类的函数的访

    问权限否则编译报错

    4:子类重写父类的函数的时候,返回值类型必须是父类函数的返回值类型或该返回值类型的子类。不能返回比父类更大的数据类型:如子类函数返回值类型是Object

     

          1:定义 A B  C B extends A 

          2Father类中定义A getA();

          3Son 类中重写getA(); 方法,尝试将返回值修改为BC ,Object

              1B编译通过

              2C 编译失败 ,没有继承关系

              3Object编译失败,比父类的返回值类型更大

    class A {
    
    }
    
    class B extends A {
    
    }
    
    class C {
    
    }
    class Father {
        String name;
    
        void eat() {
            System.out.println("吃窝窝");
        }
    
        // 定义一个函数,获取A类的对象,
        A getA() {
            return new A();
        }
    
    }
    
    class Son extends Father {
    
        public void eat() { // 继承可以使得子类增强父类的方法
            System.out.println("来两杯");
            System.out.println("来俩小菜");
            super.eat();
            System.out.println("来一根");
        }
    
        // B类是A类的子类
        B getA() {
            return new B();
        }
    }
    
    class Demo8 {
    
        public static void main(String[] args) {
            Son s = new Son();
            s.eat();
    
        }
    }

    7:子类对象查找属性或方法时的顺序:

       1:原则:就近原则。

    如果子类的对象调用方法,默认先使用this进行查找,如果当前对象没有找到属性或方法,找当前对象中维护的super关键字指向的对象,如果还没有找到编译报错,找到直接调用。

    8:重载和重写的不同

       1:重载(overload) 

          1:前提:所有的重载函数必须在同一个类中

            2:特点:

                 函数名相同,参数列表不同,与其他的无关(访问控制符、返回值类型)

          3:不同:

              个数不同顺序不同、类型不同

       2:重写(override)

            1:前提:继承

          2:特点:

                函数名必须相同、参数列表必须相同。

                子类的返回值类型要等于或者小于父类的返回值

    9:重写练习

          描述不同的动物不同的叫法

          1:定义动物类

              有名字,有吃和叫的方法

          2:定义狗继承动物重写父类吃和叫的方法

          3:定义猫继承动物重写父类吃和叫的方法

    class Animal{
        int x=1;
        String name;
        
        void eat(){
            System.out.println("吃东西");
        }
        void shout(){
            System.out.println("我是动物");
        }
    }
    
    class Dog extends Animal{
        
        
        void eat(){
            System.out.println("啃骨头");
        }
        void shout(){
            System.out.println("旺旺");
        }
        void eat(String food){
            System.out.println("吃:"+food);
        }
    }
    class Cat extends Animal{
    
        void eat(){
            System.out.println("吃老鼠");
        }
        void shout(){
            System.out.println("喵喵");
        }
    }
    
    class Demo9{
    
        public static void main(String[] args){
            Dog d=new Dog();
            d.shout();
            d.eat();
            
            Cat c=new Cat();
            c.shout();
            c.eat();
            System.out.println();
             }
    }

    1.6   instanceof 关键字

       1:快速演示instanceof

    Person p=new Person();

           System.out.println( p instanceof Person);

     

       2instanceof是什么?

          1:属于比较运算符:

           2instanceof关键字:该关键字用来判断一个对象是否是指定类的对象。

           3:用法:

                  对象  instanceof ;  

           该表达式是一个比较运算符,返回的结果是boolea类型  true|false

       注意:使用instanceof关键字做判断时,两个类之间必须有关系。

    3:案例

    定义一个功能表函数,根据传递进来的对象的做不同的事情,如果是狗让其看家,如果是猫让其抓老鼠

          1:定义动物类

          2:定义狗类继承动物类

          3:定义猫类继承动物类

          4:定义功能根据传入的动物,执行具体的功能

          5instanceof好处

              1:可以判断对象是否是某一个类的实例

    /*
     instanceof
     比较运算符
     检查是否是类的对象
         1:可以判断对象是否是某一个类的实例
         用法
         对象  instanceof 类; 
         
     案例
    定义一个功能函数,根据传递进来的对象的做不同的事情
        如果是狗让其看家,如果是猫让其抓老鼠
    1:定义动物类
    2:定义狗类继承动物类
    3:定义猫类继承动物类
    4:定义功能根据传入的动物,执行具体的功能
     */
    
    class Animal {
    
        String name;
    
        void eat() {
            System.out.println("吃东西");
        }
    
        void shout() {
            System.out.println("我是动物");
        }
    }
    
    class Dog extends Animal {
    
        void eat() {
            System.out.println("啃骨头");
        }
    
        void shout() {
            System.out.println("旺旺");
        }
    
    }
    
    class Cat extends Animal {
    
        void eat() {
            System.out.println("吃老鼠");
        }
    
        void shout() {
            System.out.println("喵喵");
        }
    }
    
    class Demo11 {
    
        public static void main(String[] args) {
    
            Demo11 d = new Demo11();
    
            // 对象 instanceof 类;
            System.out.println(d instanceof Demo11);
    
             d.doSomething(new Dog());
            d.doSomething(new Cat());
        }
    
        // 定义一个功能函数,根据传递进来的对象的做不同的事情
        // 如果是狗让其看家,如果是猫让其抓老鼠
        // 对象 instanceof 类;
        void doSomething(Animal a) {
            if (a instanceof Dog) {
                a.eat();
                a.shout();
                System.out.println("小狗看家");
            } else if (a instanceof Cat) {
                a.eat();
                a.shout();
                System.out.println("抓老鼠");
            }
        }
    }

    练习:

         byte[] bs = new byte[] { 1, 2, 3 };
            int[] is = new int[] { 1, 2, 3 };
            String[] ss = new String[] { "jack", "lucy", "lili" };
            System.out.println(bs instanceof byte[]); // true
            System.out.println(is instanceof int[]); // true
            System.out.println(ss instanceof String[]); // true
            // System.out.println(bs instanceof int[]); // 不可转换的类型

     

     

    author@nohert
  • 相关阅读:
    CGI(通用网关接口)
    PHP简介
    SEO搜索引擎优化/URL
    使用表单标签,与用户交互
    认识<img>标签,为网页插入图片
    使用mailto在网页中链接Email地址
    使用<a>标签,链接到另一个页面
    1037. Magic Coupon (25)
    1038. Recover the Smallest Number (30)
    1034. Head of a Gang (30) -string离散化 -map应用 -并查集
  • 原文地址:https://www.cnblogs.com/gzgBlog/p/13584252.html
Copyright © 2011-2022 走看看