9继承进阶_抽象类_接口

9继承进阶_抽象类_接口

导语:

想到在写

  1. 子父类中成员变量的特点
  2. 子父类中成员函数的特点。★★★★★
  3. 子父类中构造函数的特点。★★★★★
  4. final关键字的使用,重点在于常量的定义
  5. 抽象类的由来,犬科示例,抽象类的特点,细节问题(四问,必须懂)。
  6. 抽象类练习,员工数据建模。★★★★★
  7. 接口的由来,定义,实现,多实现,继承并实现,接口的特点,接口的多继承。★★★★★

1. 子父类中成员变量的特点

 /*
    继承出现后,在代码中的体现
    
    重点在在于成员的体现:
    1,成员变量。重点明确原理。
        特殊情况:
            子父类中定义了一模一样的成员变量。
            都存在于子类对象中。
            如何在子类中直接访问同名的父类中的变量呢?
            通过关键字 super来完成。
    
            super和this的用法很相似。
            this:代表的是本类的对象的引用。
            super:代表的是父类的内存空间。
    
            注意:这种情况开发见不到,因为父类一旦描述完了属性,子类直接使用就可以了。
    
    2,成员函数。
    3,构造函数。
    */
    
    //父类。
    class Fu
    {
        /*private int num1 = 3;*///父类中私有的内容子类不可以直接访问。
        int num = 3;
    }
    
    class Zi extends Fu
    {
        /*int num2 = 4;*/
        int num = 4;
        void show()
        {
    //        System.out.println("num1="+num1);
    //        System.out.println("num2="+num2);
    
            System.out.println("zi num="+this.num);
            System.out.println("fu num="+super.num);
    
        }
    }
    
    class ExtendsDemo 
    {
        public static void main(String[] args) 
        {
            Zi z = new Zi();
            z.show();
        }
    } 

2. 子父类中成员函数的特点。★★★★★

 /*
    【子父类中成员函数的特点】
    特殊情况:
    子父类中的定义了一模一样的函数。
    运行的结果:子类的函数在运行。
    这种情况在子父类中,是函数的另一个特性:override(重写,覆盖,复写)
    
    【重写什么时候用?】
    举例:
    //描述手机。
    class Phone
    {
        int number;
        //打电话。
        void call(){}
        //来电显示。
        void show()
        {
            sop("电话号码.."+number);
        }
    }
    Phone p = new Phone();
    p.show();
    
    随着电话的升级,只显示号码不爽,希望显示姓名,大头贴。
    修改源码,虽然费劲但是可以解决,不利于后期的维护和扩展。
    为了扩展方便。新功能是不是新的电话具备呢?
    单独描述单独封装。新电话也是电话中的一种。继承。直接获取父类中的功能。
    但是新电话的来显功能已经变化了。需要重新定义。
    那么定义一个新功能合适吗?比如newShow,不合适,因为父类已经将来显功能定义完了,
    子类完全不需要重新定义新功能。直接用就可以了。如果子类的来显功能内容不同。
    直需要保留来显功能,定义子类的内容即可:这就是重写的应用!
    
    class NewPhone extends Phone
    {
        String name;
        String picPath;//图片路径。
        void show()
        {
            //sop("电话号码");
            super.show();//如果还需要父类中原有的部分功能,可以通过super调用。
            sop("姓名"+name);
            sop("大头贴"+picPath);
        }
    }
    
    
    【重写(覆盖)的注意事项】
    
    1,子类覆盖父类,必须保证全要大于或者等于父类的权限。
    Fu:
    private void show(){}
    
    Zi:
    public void show(){}
    2,静态覆盖静态。
    
    
    写法上稍微注意:必须一模一样:函数的返回值类型 函数名 参数列表都要一样。
    
    
    
    【总结】
    当一个类是另一个类中的一种时,可以通过继承,来扩展功能。
    如果从父类具备的功能内容需要子类特殊定义时,使用重写。
    
    */
    
    class Fu
    {
        int show()
        {
            System.out.println("fu show run");
            return 0;
        }
    }
    class Zi extends Fu
    {
        void show()
        {
            System.out.println("zi show run");
        }
    }
    class ExtendsDemo2 
    {
        public static void main(String[] args) 
        {
            Zi z = new Zi();
            z.show();
        }
    } 

3. 子父类中构造函数的特点。★★★★★

 /*
    【子父类中成员函数的特点】
    特殊情况:
    子父类中的定义了一模一样的函数。
    运行的结果:子类的函数在运行。
    这种情况在子父类中,是函数的另一个特性:override(重写,覆盖,复写)
    
    【重写什么时候用?】
    举例:
    //描述手机。
    class Phone
    {
        int number;
        //打电话。
        void call(){}
        //来电显示。
        void show()
        {
            sop("电话号码.."+number);
        }
    }
    Phone p = new Phone();
    p.show();
    
    随着电话的升级,只显示号码不爽,希望显示姓名,大头贴。
    修改源码,虽然费劲但是可以解决,不利于后期的维护和扩展。
    为了扩展方便。新功能是不是新的电话具备呢?
    单独描述单独封装。新电话也是电话中的一种。继承。直接获取父类中的功能。
    但是新电话的来显功能已经变化了。需要重新定义。
    那么定义一个新功能合适吗?比如newShow,不合适,因为父类已经将来显功能定义完了,
    子类完全不需要重新定义新功能。直接用就可以了。如果子类的来显功能内容不同。
    直需要保留来显功能,定义子类的内容即可:这就是重写的应用!
    
    class NewPhone extends Phone
    {
        String name;
        String picPath;//图片路径。
        void show()
        {
            //sop("电话号码");
            super.show();//如果还需要父类中原有的部分功能,可以通过super调用。
            sop("姓名"+name);
            sop("大头贴"+picPath);
        }
    }
    
    
    【重写(覆盖)的注意事项】
    
    1,子类覆盖父类,必须保证全要大于或者等于父类的权限。
    Fu:
    private void show(){}
    
    Zi:
    public void show(){}
    2,静态覆盖静态。
    
    
    写法上稍微注意:必须一模一样:函数的返回值类型 函数名 参数列表都要一样。
    
    
    
    【总结】
    当一个类是另一个类中的一种时,可以通过继承,来扩展功能。
    如果从父类具备的功能内容需要子类特殊定义时,使用重写。
    
    */
    
    class Fu
    {
        int show()
        {
            System.out.println("fu show run");
            return 0;
        }
    }
    class Zi extends Fu
    {
        void show()
        {
            System.out.println("zi show run");
        }
    }
    class ExtendsDemo2 
    {
        public static void main(String[] args) 
        {
            Zi z = new Zi();
            z.show();
        }
    } 

4. final关键字的使用,重点在于常量的定义

 /*
    继承的弊端:打破封装性。
    不让其他类继承该类,就不会有重写。
    怎么能实现呢?通过Java中的一个关键字来实现,final(最终化)。
    
    【final关键字】
    是一个修饰符,可以修饰类,方法,变量(成员变量,局部变量,静态变量)。
    【特点】
    1,final修饰的类是一个最终类,不能在派生子类。
    如果类中从出现部分可以重写,部分不可以?怎么办?只要让指定的方法最终化就可以了。
    2,final修饰的方法是最终方法,不可以给重写。
    3,final修饰的变量是一个常量,只能被赋值一次。
    【什么时候会在程序中定义final常量呢?】
    当程序中一个数据使用时是固定不变的,这时为了增加阅读性,可以该该数据起个名字。
    这就是变量,为了保证这个变量的值不被修改,加上final修饰,这就一个阅读性很强的常量。
    书写规范,被final修饰的常量名所有的字母都是大写的。如果由多个单词组成单词间通过 _ 连接。
    
    
    */
    /*final*/class Fu
    {
        /*final*/ void show()
        {
            //调用到一些系统的功能。
            //功能的内容是不可以改变的。
        }
    }
    
    class Zi extends Fu
    {
        static final int number = 9;//最终化的是显示初始化值。
        static final double PI = 3.14;
        //重写
        void show()
        {
            final int count = 21;
    //        count = 2;
            System.out.println(count);
        }
    }
    
    
    class FinalDemo 
    {
        public static void main(String[] args) 
        {
            System.out.println("Hello World!");
        }
    } 

5. 抽象类的由来,犬科示例,抽象类的特点,细节问题(四问,必须懂"。

 /*
    描述狗,行为:吼叫。
    描述狼,行为:吼叫。
    发现他们之间有共性,可以进行向上抽取。
    当然是抽取它们的所属共性类型:犬科。
    犬科这类事物:都具备吼叫行为,但是具体怎么叫,是不确定的,是由具体的子类来明确的。
    这时在描述犬科时,发现了有些功能不具体,这些不具体的功能,需要在类中标识出来,通过java中的关键字abstract(抽象)。
    定义了抽象函数的类也必须被abstract关键字修饰,被abstract关键字修饰的类是抽象类。
    */
    //抽象类:在描述事物时,没有足够的信息描述一个事物,这时该事物就是抽象事物。
    
    /*
    【抽象类的特点】
    1,抽象类和抽象方法都需要被abstract修饰。
    抽象方法一定要定义在抽象类中。
    2,抽象类不可以创建实例,原因:调用抽象方法没有意义。
    3,只有覆盖了抽象类中所有的抽象方法后,其子类才可以实例化。
    否则该子类还是一个抽象类。
    
    
    之所以继承,更多的是在思想,是面对共性类型操作会更简单。
    
    
    【细节问题】
    1,抽象类一定是个父类?    
        是的,因为不断抽取而来的。
    
    2,抽象类是否有构造函数?
        有,虽然不能给自己的对象初始化,但是可以给自己的子类对象初始化。
        抽象类和一般类的异同点:
        相同:
            1,它们都是用来描述事物的。
            2,它们之中都可以定义属性和行为。
    
        不同:
            1,一般类可以具体的描述事物。
                抽象类描述事物的信息不具体
            2,抽象类中可以多定义一个成员:抽象函数。
            3,一般类可以创建对象,而抽象类不能创建对象。
    
    3,抽象类中是否可以不定义抽象方法。
        是可以的,那这个抽象类的存在到底有什么意义呢?仅仅是不让该类创建对象。
    
    
    4,抽象关键字abstract不可以和哪些关键字共存?    
        1,final:
        2,private:
        3,static:
    
    
    */
    
    
    abstract class 犬科 //extends Object
    {
        static abstract void 吼叫();//抽象函数。需要abstract修饰,并分号;结束
    }
    
    
    //代码体现。
    class Dog extends 犬科
    {
        void 吼叫()
        {
            System.out.println("汪汪汪汪");
        }
    }
    
    class Wolf extends 犬科
    {
        void 吼叫()
        {
            System.out.println("嗷嗷嗷嗷");
        }
    }
    
    
    
    class  AbstractDemo
    {
        public static void main(String[] args) 
        {
            System.out.println("Hello World!");
        }
    } 

6. 抽象类练习,员工数据建模。★★★★★

/*
    需求:公司中程序员有姓名,工号,薪水,工作内容。
    项目经理除了有姓名,工号,薪水,还有奖金,工作内容。
    对给出需求进行数据建模。
    
    在问题领域中先找寻其中涉及的对象。
    程序员
        属性:姓名,工号,薪水
        行为:工作
    
    项目经理
        属性:姓名,工号,薪水,奖金
        行为:工作
    
    这些对象是否有关系呢?因为发现了他们之间的共性,应该存在着关系。
    可以将他们的共性向上抽取到共性类型:员工。
    员工:
        属性:姓名,工号,薪水
        行为:工作
    发现员工的工作内容本身就不具体。应该是抽象的,由具体的子类来体现的。
    
    一定要动手!
    
    
    */
    
    abstract class Employee
    {
        private String name;
        private String id;
        private double pay;
        /**
        构造一个员工对象,一初始化就具备着三个属性。
        */
        public Employee(String name,String id,double pay)
        {
            this.name = name;
            this.id = id;
            this.pay = pay;
        }
        /**
        工作行为。
        */
        public abstract void work();
    }
    
    //具体的子类:程序员。
    class Programmer extends Employee
    {
        public Programmer(String name,String id,double pay)
        {
            super(name,id,pay);
        }
        public void work()
        {
            System.out.println("code....");
        }
    }
    
    //具体的子类:经理。
    class Manager extends Employee
    {
        //特有属性。
        private double bonus;
        public Manager(String name,String id,double pay,double bonus)
        {
            super(name,id,pay);
            this.bonus = bonus;
        }
        public void work()
        {
            System.out.println("manage");
        }
    }
    
    class AbstractTest 
    {
        public static void main(String[] args) 
        {
            System.out.println("Hello World!");
        }
    } 

7. 接口的由来,定义,实现,多实现,继承并实现,接口的特点,接口的多继承。★★★★★

 /*
    抽象类中可以定义抽象方法的 。
    当一个抽象类中的方法全是抽象的。
    这时,可以通过另一种特殊的形式来体现。
    
    用接口来表示。
    
    接口该如何定义呢?
    interface
    
    
    abstract class Demo
    {
        abstract void show1();
        abstract void show2();
    }
    */
    /*
    接口中的成员已经被限定为固定的几种。
    【接口的定义格式先介绍两种:】
    1,定义变量,但是变量必须有固定的修饰符修饰,public static final 所以接口中的变量也称之为常量。
    2,定义方法,方法也有固定的修饰符,public abstract
    接口中的成员都是公共的。
    
    【接口的特点】
    1,接口不可以创建对象。
    2,子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。
        否则子类是一个抽象类。
    
    */
    interface Demo//定义一个名称为Demo的接口。
    {
        public static final int NUM = 3;
        public abstract void show1();
        public abstract void show2();
    }
    //定义子类去覆盖接口中的方法。子类必须和接口产生关系,类与类的关系是继承,类与接口之间的关系是 实现。通过 关键字 implements
    class DemoImpl implements Demo//子类实现Demo接口。
    {
        //重写接口中的方法。
        public void show1(){}
        public void show2(){}
    }
    
    
    
    /*
    【接口最重要的体现】
    解决多继承的弊端。将多继承这种机制在java中通过多实现完成了。
    
    
    */
    /*
    interface A
    {
        void show1();
    }
    interface B
    {
        void show2();
    }
    class C implements A,B// 多实现。同时实现多个接口。
    {
        public void show1(){}
        public void show2(){}
    }
    */
    /*
    【怎么解决多继承的弊端呢?】
    弊端:多继承时,当多个父类中有相同功能时,子类调用会产生不确定性。
    其实核心原因就是在于多继承父类中功能有主体,而导致调用运行时,不确定运行哪个主体内容。
    为什么多实现就解决了呢?
    因为接口中的功能都没有方法体,由子类来明确。
    
    interface A
    {
        void show();
    }
    interface B
    {
        void show();
    }
    class C implements A,B// 多实现。同时实现多个接口。
    {
        public void show();
    }
    
    C c = new C();
    c.show();
    
    
    */
    
    /*
    【基于接口的扩展。】
    
    class Fu
    {
        public void show(){}
    }
    //子类通过继承父类扩展功能,通过继承扩展的功能都是子类应该具备的基础功能。
    //如果子类想要继续扩展其他类中的功能呢?这时通过实现接口来完成。
    interface Inter
    {
        pulbic void show1();
    }
    class Zi extends Fu implements Inter
    {
        public void show1()
        {
    
        }
    }
    
    接口的出现避免了单继承的局限性。
    父类中定义的事物的基本功能。
    接口中定义的事物的扩展功能。
    
    
    
    */
    
    /*
    【接口出现后的一些小细节】
    1,类与类之间是继承(is a)关系,类与接口之间是实现(like a)关系,
        接口与接口之间是继承关系,而且可以多继承。
    */
    interface InterA
    {
        void show1();
    }
    interface InterAA
    {
        void show11();
    }
    interface InterB extends InterA,InterAA//接口的多继承。
    {
        void show2();
    }
    
    class Test implements InterB
    {
        public void show1(){}
        public void show2(){}
        public void show11(){}
    }
    
    
    class InterfaceDemo 
    {
        public static void main(String[] args) 
        {
            DemoImpl d = new DemoImpl();
            d.show1();
            d.show2();
    
        }
    }
发布了21 篇原创文章 · 获赞 0 · 访问量 53

猜你喜欢

转载自blog.csdn.net/qq_42745404/article/details/105036728