• SE -- 继承


    继承

    概述: 多个类中存在相同的属性和行为时,将这些内容抽取到单独的一个类中,那么多个类无需再定义这些属性和行为,只要继承单独的那个类即可。

    多个类可以称为子类,单独这个类称为父类或者超类。

    子类可以直接访问父类中的非私有的属性和行为。

    通过extends关键字让类与类之间产生继承关系。 class SubDemo extends Demo{}

    继承的出现提高了代码的复用性;继承的出现让类与类之间产生了关系,提供了多态的前提。

    特点:java只支持单继承,不支持多继承;支持多层继承。

    注意:不要仅为了获取其他类中某个功能而去继承;类与类之间要有所属关系 is a xx1是xx2的一种

    聚集:has a

    聚合:班级里面有学生;球队中有球员

    组合:心脏是人体的一部分,手人体的一部分(紧密联系程度不同)

    子父类出现后,类中成员的特点

    1、变量

    如果子类中出现非私有的同名成员变量,子类要访问本类中的成员变量,用this;要访问父类中的成员变量,用super。

    2、函数

    3、构造函数

    super关键字

    this代表本类应用;super代表父类应用;当子父类出现同名成员时,可以用super进行区分;子类要调用父类构造函数时,可以使用super语句

    函数覆盖(override)

    子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为复写或者重写;父类中的私有方法不可以被覆盖。在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。

    覆盖:

    1、覆盖时,子类方法权限一定要大于等于父类方法权限

    2、静态只能覆盖静态

    应用:

    当子类需要父类的功能,而功能主体子类有自己特定内容时,可以复写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。

    子类的实例化过程

    子类中所有的构造函数默认都会访问父类中空参数的构造函数

    因为每一个构造函数的第一行都有一条默认的语句 super()

    子类会具备父类中的数据,所以要明确父类是如何对这些数据初始化的

    当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数。

    class Fu
    {
        Fu()
        {
            System.out.println("Fu run...");
        }
    }
    
    class Zi extends Fu
    {
        Zi()
        {
            //super()
            System.out.println("Zi run...");
        }
        Zi(int x)
        {
            //super()
            System.out.println("Zi run..." + x);
        }
    }
    
    class ExtendsDemo
    {
        public static void main(String[] args)
        {
            Zi z = new Zi();
            Zi z1 = new Zi(4);
        }
    }
    
    /*
    ---------- java ----------
    Fu run...
    Zi run...
    Fu run...
    Zi run...4
    
    输出完成 (耗时 0 秒) - 正常终止
    */

    ?子类一定要访问父类中的构造函数

    因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问以下父类的构造函数,所以要访问父类的构造函数,可以通过定义super()语句访问。

    final关键字

    1、final可以修饰类、方法、变量。

    2、final修饰的类不可以被继承。

    3、final修饰的方法不可以被覆盖。

    4、final修饰的变量是一个常量,只能被赋值一次。常量的书写规范:所有字母都大写,如果多个单词组成,单词间通过_连接

    5、内部类只能访问被final修饰的局部变量

    修饰类 public final

    抽象类

    抽象:抽象就是从多个事物中将共性的、本质的内容抽取出来。

    抽象类:java中可以定义没有方法体的方法。该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。抽象方法和抽象类都必须被abstract修饰

    抽象类不可以被new创建对象,因为调用抽象方法没有意义。

    抽象类中的抽象方法要像被使用 必须被子类覆写所有的抽象方法后,建立子类对象使用,如果子类只覆写了部分抽象方法,那么子类还是一个抽象类。

    抽象方法:多个对象都具备相同的功能,但是功能具体内容有所不同。那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。

    疑惑点:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。

    /*
    员工: 姓名 工号 工资 name id pay
    经理:继承员工 + 奖金bonus
    */
    abstract class Employee
    {
        private String name;
        private String id;
        private double pay;
        //员工初始化
        Employee(String name, String id, double pay)
        {
            this.name = name;
            this.id = id;
            this.pay = pay;
        }
    
        //方法
        public abstract void work();
    }
    
    class Manager extends Employee
    {
        private int bonus;
        //经理初始化
        Manager(String name, String id, double pay,int bonus)
        {
            super(name,id,pay);
            this.bonus = bonus;
        }
        public void work()
        {
            System.out.println("manager work...");
        }
    }
    
    class Pro extends Employee
    {
        Pro(String name, String id, double pay)
        {
            super(name,id,pay);
        }
        public void work()
        {
            System.out.println("Pro work...");
        }
    }
    
    
    public class  AbstarctDemo
    {
        public static void main(String[] args) 
        {
            Manager mg = new Manager("wu","1",1.1,1);
            mg.work();
        }
    }
    /*
    ---------- java ----------
    manager work...
    
    输出完成 (耗时 0 秒) - 正常终止
    */

    模板方法设计模式:在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去。由该类的子类去完成

    /*
    需求: 获取一段程序运行的时间
    原理: 获取程序开始和结束的时间并相减
    获取时间 currentTimeMillis()
    */
    abstract class GetTime
    {
        public final void getTime()
        {
            long start = System.currentTimeMillis();
            runCode();
            long end = System.currentTimeMillis();
            System.out.println("
    end-start:" + (end-start));
        }
        public abstract void runCode();
    }
    
    class SubTime extends GetTime
    {
        public void runCode()
        {
            for(int x=0; x<1000; x++)
            {
                System.out.print(x);
            }
        }    
    }
    
    class TemplateDemo 
    {
        public static void main(String[] args) 
        {
            SubTime st = new SubTime();
            st.getTime();
        }
    }
    /*
    end-start:12
    */

    接口

    接口 innterface{}

    接口中的成员修饰符是固定的:

    成员常量:public static final

    成员函数:public abstarct

    接口的出现将“多继承”通过另一种形式体现出来,即“多实现”implement。

    特点

    1、接口是对外暴露的规则

    2、接口是程序的功能扩展。

    3、接口可以用来多实现。

    4、类与接口直接是实现关系,而且类可以继承一个类的同时实现多个接口。

    5、接口与接口之间可以有继承关系

    多态

    某一类事物的多种存在形态。

    例如:猫这个对象对应的类类型是猫类型,也是动物的一种;父类型引用指向了子类对象。

    体现:父类或者接口的引用指向或者接受自己的子类对象。

    作用:多态的存在提高了程序的扩展性和后期可维护性。只能使用父类的引用访问父类的成员。

    前提:需要存在继承或者实现关系。要有覆盖操作。

    向上转型: Animal a =  new Cat()

    向下转型[强制将父类的引用转成子类类型]: Cat c = (Cat)a

    多态的特点

    成员函数:

    编译时,要查看引用变量所属的类中是否有所调用的成员。

    运行时,要查看对象所属的类中是否有所调用的成员

    成员变量:只看引用变量所属的类。

    静态成员函数特点:无论编译还是运行,都参考左边。

    object类

    方法

    equals :对对象是否相同的方法,可覆盖

    class Demo //extends Object
    {
    }
    
    public class ObjectDemo 
    {
        public static void main(String[] args) 
        {
            Demo d1 = new Demo();
            Demo d2 = new Demo();
            Demo d3 = d1;
            System.out.println(d1.equals(d2));
            System.out.println(d1.equals(d3));
            System.out.println(d1==d2);
            System.out.println(d1==d3);
        }
    }
    /*
    ---------- java ----------
    false             //比较内存地址值
    true
    false
    true
    */
    //数值比较
    class Demo //extends Obect
    {
        private int num;
        Demo(int num)
        {
            this.num = num;
        }
        //覆写父类方法
        public boolean equals(Object obj)
        {
            //向下转型
            Demo d = (Demo)obj;
            if(!(d instanceof Demo))
                return false;
            return this.num == d.num;
        }
    }
    class Person
    {
    }
    
    class ObjectDemo
    {
        public static void main(String[] args)
        {
            Demo d1 = new Demo(4);
            Demo d2 = new Demo(5);
            Person p1 = new Person();
            System.out.println(d1.equals(d2));
            System.out.println(p1.equals(d1));
        }
    }
    
    /*
    ---------- java ----------
    false
    false
    */

    toString 对象字符串表示形式

    getClass().getName() + '@' + Integer.toHexString(hashCode())
    

    内部类

    定义:将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)

    特点:

    1、内部类可以直接访问外部类中的成员,包括私有成员。

    2、外部类要访问内部类中的成员必须要建立内部类的对象

    class Outer
    {
        private int x = 3;
    
        //内部类可以直接访问外部类的成员,包括私有。
        //外部类要访问内部类必须建立内部类对象 private class Inner 可以被私有,类中被访问
        class Inner
        {
            int x = 4;
            void function()
            {
                int x = 6;
                /*
                ---------- java ----------
                inner:6
                inner:4
                inner:3
                */
                System.out.println("inner:" + x);
                System.out.println("inner:" + this.x);
                System.out.println("inner:" + Outer.this.x);
            }
        }
    
        void method()
        {
            Inner in = new Inner();
            in.function();
        }
    }
    
    class InnerClassDemo 
    {
        public static void main(String[] args) 
        {
            Outer ot = new Outer();
            ot.method();
            //直接访问内部类成员
            /*
            Outer.Inner in1 = new Outer().new Inner();
            in1.function();
            */
        }
    }

    位置:

    成员位置:

    1、可以被private static成员修饰符修饰 

    2、被static修饰的内部类只能访问外部类中的静态成员

    Q1 在外部其他类中,如何直接访问static内部类的非静态成员?

    new Outer.Inner().function();

    Q2 在外部其他类中,如何直接访问static内部类的静态成员?

    Outer.Inner.function()

    注意:当内部类定义了静态成员,该内部类必须是static的

    当外部类中的静态方法访问内部类时,内部类也必须是静态的。

    class Outer
    {
        private static int x = 3;
    
        //内部类可以直接访问外部类的成员,包括私有。
        //外部类要访问内部类必须建立内部类对象 private class Inner 可以被私有,类中被访问
        //静态内部类 InnerClassDemo.java:12: 错误: 无法从静态上下文中引用非静态 变量  System.out.println("inner:" + x);
        static class Inner
        {
            void function()
            {
                System.out.println("inner:" + x);
            }
        }
    
        void method()
        {
            Inner in = new Inner();
            in.function();
        }
    }
    
    class InnerClassDemo 
    {
        public static void main(String[] args) 
        {
            Outer ot = new Outer();
            ot.method();
        }
    }

    局部位置:

    1、可以直接访问外部类中的成员

    2、同时可以访问所在局部中的局部变量,但必须是被final修饰的

    class Outer
    {
        int x = 3;
        void method(int x)
        {
            int y =4;
            class Inner
            {
                void function()
                {
                    System.out.println("x = " + x);
                    System.out.println("y = " + y);
                }
            }
            new Inner().function();
        }
    }
    
    public class InnerClassDemo
    {
        public static void main(String[] args)
        {
            new Outer().method(4);
        }
    }
    
    /*
    ---------- java ----------
    x = 3
    y = 4
    */

    Q:定义内部类

    当描述事物时,事物的内部还有事物,该事物用内部类描述。因为内部类事物在使用外部类事物的内容。例如:人体有器官等。

    匿名内部类:就是内部类的简化写法

    前提:内部类可以继承一个外部类或者实现接口

    格式:new 外部类名或者接口名(){覆盖类或者接口欧中的代码/自定义内容}

    Q1:建立一个戴内容的外部类或者接口的子类匿名内部类。

    异常

    Throwable

    throws throw

    异常处理

    自定义异常

    异常细节

    classpath

    包之间的访问

    import

    Jar包

    拼命敲
  • 相关阅读:
    leetCode21. 合并两个有序链表
    (flag)每日三道面试题(4.25)
    每日三加一面试题(4.21)
    按照顺序执行异步函数
    javascript Proxy 代理模式深度监听对象、数组变化
    数据结构与算法(二) 线性表一
    This关键字
    数据结构与算法(一)
    Git报错信息
    MakeDown语法学习
  • 原文地址:https://www.cnblogs.com/wuyuwuyueping/p/9059045.html
Copyright © 2020-2023  润新知