• JAVA基础--面向对象08


    一、final关键字

        有的时候不想别人重写我的方法,使用final关键字修饰该方法,final:最后的,最终的,可以修饰类、修饰函数、修饰变量,修饰类:该类不能被继承;直接写在class关键字前面

      

    修饰函数:函数不能被重写;直接写在函数返回值类型前面;

      

    修饰变量:变量的值不能被修改,可以成为常量;直接写在变量的数据类型前面;

    因为被final修饰的变量的值不能改变,所以被fianl修饰的变量有叫做常量;

    此时,我们给他的命名的书写规范:全部字母都要大写;多个单词,可以使用下划线(_)分开;

    如:       private static final double PI = 3.14;

    变量的值不能改变,指的是直接保存在变量中的内容不能改变;

    如果被final修饰的变量是一个引用类型的数据,那么通过这个引用改变堆空间中的数据,不会报错;

    二、抽象类

      1. 抽象类的产生 

        需求:创建类描述猫和狗的行为;

        猫的行为:抓老鼠;吃鱼;

        狗的行为:看家;吃骨头;

        

        

        

    分析:

    因为猫和狗都动物,所以可以让猫和狗分别继承动物类,然后将共同东西抽取到动物类中;

    小结:当事物的功能描述不清,只能表示有这个功能时,就应该使用抽象修饰该功能,这个功能就是抽象的功能;

    如果一个类中有抽象的功能,那么这个类也是抽象的类;

      2. 抽象的特点

        a. 抽象类不能实例化     

          因为抽象类,表示一个描述不清的事物,所以不能实例化;

          

          b.子类继承抽象类,必须实现父类的所有抽象函数,否则子类也是抽象的     

            抽象类,必须由子类去继承,继承的子类必须实现父类中所有的抽象方法;

            

      c. 抽象函数必须放在抽象类中 

           

        因为类中有抽象函数,表示描述不清的功能,所以整个类所描述的事物,也是描述不清的,所以需要将类也定义为抽象的;

      c. 注意事项

        c.1 抽象类一定是父类吗?

         是,因为抽象类就是通过不同的子类向上抽取共性信息得倒的,抽线类必须由子类去继承和重写抽象函数;

          c.2  抽象类中有构造方法吗?     

          必须有,因为抽象类需要由子类去继承,子类实例化的时候,要调用父类的构造函数,抽象类的构造函数作用是初始化本类中的成员变量的;

        

      c.3  抽象类中可以不书写抽象方法吗?  

        可以;可以只有非抽象的成员;

        同样,不能实例化;

      c.4 抽象类中可以定义非抽象的方法吗?(抽象类中可以书写普通方法和成员变量)   

        抽象类中除了抽象函数,还可以定义所有一般类中可以定义的成员;

      c.5 抽象关键字abstract不能和哪些修饰符关键字共存?  

        因为抽象的函数只有被继承的子类重写了,才可以使用,所以不能和private以及final关键字一起使用;

        static:   因为静态的函数可以直接使用类名调用,所以也不能使用static修饰抽象函数;

      c.6 抽象类什么时候使用?

        当描述的功能不确定,不知道具体怎么实现的时候,就需要使用抽象函数,这是类也是抽象的;

        不想实例化这个类(包括自己也不行),但是允许别人继承,也可以使用抽象类;

      3. 抽象类应用    

        需求:描述Hr和程序员:

        

          

        有共同的

        

        

    三、多态

      1. 多态的引入

            

      狗;哈士奇;二哈;动物;生物;汪星人;畜生……   

      生活中的一个实实在在的事物,我们可以使用不同的状态去描述,这就是多态;   

      而且我们在生活中,我们更习惯使用抽象的、一般化的概念来描述一个具体的事物;

        :       啤酒;白酒;黄酒;红酒……

      饭:       米饭;面条;饺子;包子……

      使用一般化、抽象化的概念指代一个具体的事物,就是多态在生活中的体现;

      2. JAVA中的多态

        

           

        上面代码中红框部分使用了多态,结论:在java中,多态,指的是父类型引用指向子类实例对象;(接口类型引用指向实现类对象

        a. 多态的使用前提    

          生活中的前提:被指代的事物确实 是 用于描述它的那个概念 的一个特例;

          Java中的前提:必须是继承关系(或者接口实现关系);

        b.  多态的好处    

          生活中:使用多态指代事物,能够指代的范围更广泛,到了实际操作的时候,就有更多的选择;

              Java中的好处:

              描述猫和狗的行为,同时需要提供测试方法;

              首先描述和测试猫

          

        接下来描述和测试狗的行为

            

        问题:每添加一个被测试的类型的对象,都需要单独创建一个专门的功能,而且在这些测试功能中,实现是类似的;

        问题就是,代码复用性差,程序扩展性差; 

        解决:考虑使用多态,直接创建一个测试父类型的方法,然后就可以接受不同类型的对象;

        

     1 /*
     2     描述猫和狗的行为,同时需要提供测试方法;
     3 */
     4 //描述动物
     5 abstract class Animal
     6 {
     7     abstract void eat();
     8     abstract void sleep();
     9 }
    10 
    11 
    12 //描述猫的行为
    13 class Cat extends Animal
    14 {
    15     //
    16     void eat(){
    17         System.out.println("吃鱼");
    18     }
    19     //睡觉
    20     void sleep(){
    21         System.out.println("猫咪睡着了");
    22     }
    23 }
    24 //描述狗的行为
    25 class Dog extends Animal
    26 {
    27     //
    28     void eat(){
    29         System.out.println("吃骨头");
    30     }
    31     //睡觉
    32     void sleep(){
    33         System.out.println("狗狗睡着了");
    34     }
    35 }
    36 //创建测试类测试
    37 class Test2
    38 {
    39     //测试动物的行为
    40     public static void testAnimal(Animal animal){
    41         animal.eat();
    42         animal.sleep();
    43     }
    44 
    45     public static void main(String[] args) 
    46     {
    47         //使用多态指向猫的对象
    48         Animal cat = new Cat();
    49         testAnimal(cat);
    50     
    51         //使用多态指向狗的对象
    52         Animal dog = new Dog();
    53         testAnimal(dog);
    54     }
    55 } 

     

      小结:使用多态,可以提高程序的扩展性,降低代码的冗余;

      c. 多态的弊端

             

        使用父类型引用指向子类对象,不能通过父类性引用访问子类特有属性和行为;

      3. 多态的类型转换

        a. 多态的类型转换     

          自动向上转型: 将子类性对象赋值给父类型引用,可以自动进行;提升了子类对象的类型;

              

          强制向下转型:将父类型引用转为子类性引用,降低了引用的类型,需要强制转换;

               

          结论:是用强制向下转型,可以解决多态使用的弊端;

        b. 强制向下转型的问题

          

      c. instanceof 关键字  

        instanceof:   比较运算符;

           

        运算符左边是一个指向一个对象的引用(左边就是一个变量名),右边是一个类名,运算符表示的意思就是:判断左边的对象的类型是不是右边的类;

         

        结论:使用instanceof关键字,可以实时判断一个对象的类型,就可以避免强制类型转换中容易出现的类型转换异常;

      d. 多态中成员的特点   

        程序分为编译和运行两个阶段,程序中的成员,又分为静态和非静态两种,所以,要分不同情况讨论;

        

        在使用多态的程序中,编译时,不管是什么成员,编译器都看的是父类型的引用;

        

    运行时,所有成员变量都是用的是父类型的;静态函数使用的是父类型的,非静态函数使用的是子类重写的;

    总结:在使用多态时,成员的特点:

    编译期:不管什么成员,只要用到了,都要检查父类中有没有;

    运行期:所有成员变量和静态函数都是使用的父类的,非静态函数使用的是子类重写的;

    静态成员不参与多态,只有非静态成员才与多态,因为多态是和对象有关的;

    编译时都要看 等号  左边

    运行时,只有非静态函数看等号右边

      f.多态练习

     

     1 /*
     2     需求:描述老板让Hr、程序员干活;
     3 */
     4 //描述Hr
     5 class Hr
     6 {
     7     void work(){
     8         System.out.println("人事管理");
     9     }
    10 }
    11 
    12 //描述程序员
    13 class Programmer
    14 {
    15     void work(){
    16         System.out.println("敲代码改变世界!");
    17     }
    18 }
    19 //描述老板
    20 class Boss
    21 {
    22     //老板让Hr干活
    23     void letHrWork(Hr hr){
    24         hr.work();
    25     }
    26 
    27     //老板让程序员干活
    28     void letProWork(Programmer pro){
    29         pro.work();
    30     }
    31 }
    32 
    33 class Test5
    34 {
    35     public static void main(String[] args) 
    36     {
    37         Boss boss = new Boss();
    38         
    39         Hr hr = new Hr();
    40         boss.letHrWork(hr);
    41         
    42         Programmer pro = new Programmer();
    43         boss.letProWork(pro);
    44     }
    45 }

      

    传统的做法,太麻烦,需要一个一个去做;

    而实际生活中不是这样,老板一个命令,所有干活的都要去工作,所以考虑从使用多态 

     

     1 //描述打工的
     2 abstract class Worker
     3 {
     4     abstract void work();
     5 }
     6 //描述Hr
     7 class Hr extends Worker
     8 {
     9     void work(){
    10         System.out.println("人事管理");
    11     }
    12 }
    13 //描述程序员
    14 class Programmer extends Worker
    15 {
    16     void work(){
    17         System.out.println("敲代码改变世界!");
    18     }
    19 }
    20 //描述老板
    21 class Boss
    22 {
    23     void letWorkerWork(Worker worker){
    24         worker.work();
    25     }
    26 }
    27 
    28 class Test6
    29 {
    30     public static void main(String[] args) 
    31     {
    32         Boss boss = new Boss();
    33         
    34         Worker hr = new Hr();
    35         boss.letWorkerWork(hr);
    36         
    37         Worker pro = new Programmer();
    38         boss.letWorkerWork(pro);
    39     }
    40 }

     

    多态总结:

      概念:一种事物可以有多种表示形态;而且一般习惯使用更抽象、更一般化的形态表示这个事物;

      多态在Java中的体现:父类型引用指向子类实例对象;接口引用指向实现类对象;

      多态的前提:必须有继承或者接口实现的关系;

      多态的好处:提高代码的复用性,提高程序的扩展性;

      多态的弊端:不能使用子类对象特有的属性和功能;

      解决多态弊端的方法:使用强制类型转换;

      使用强制类型转换容易出现类型转换异常,解决的办法是转换前使用比较运算符:instanceof判断;

      多态使用中成员的特点:

      编译时,所有成员都看父类;

      运行时,只有非静态成员函数看子类;

      静态成员不参与多态;

    四、接口

       1. 接口的引用     

      需求:分别描述以下三种动物的行为:

        狗:吃;叫;

        猫:吃;叫;

        猪:吃;叫;

        

      接下来,需求升级:

        狗和猫经过训练,都学会了表演;

        

      2. 接口代码体现  

        a. 接口的声明格式

        接口使用关键字:interface声明;

        

        b. 接口中能书写的成员    

          接口和类不同,在接口中可以书写的内容,都已经被Java固定了:

          成员变量:    只能使用一下修饰符:public static final;

          也就是说,接口中的成员变量,都是常量;

          成员函数:    只能使用修饰符:public abstract ;

          也就是说,接口中的方法,都是公共和抽象的;

          这些修饰符,是Java在语法层面固定的,我们可以省略不写,编译器会帮我们加上;

          要写,就只能这么写,不能改写;

          

        c. 接口的实现

          接口和抽象类一样,都无法实例化,需要使用一个类来实现接口,使用关键字:implements

          

        d. 多态使用接口   

          一般开发中,都会通过多态的方式使用接口;

          接口类型的引用指向实现类的对象;

          

        3. 接口的多实现 & 多继承     

          接口的多实现

             

          小结:一个类可以实现多个接口,多个接口之间使用逗号分开;

          如果一个类实现了接口,就必须实现接口中的所有方法,否则这个类应该定义为抽象的;

          当使用其中一个接口来利用多态的形式使用实现类的对象时,只能访问属于这个接口的属性和方法;

                

          接口的多继承

          接口和类之间是实现的关系,接口和接口之间是继承的关系;而且接口支持多继承;

      4. 接口的使用思想

        a. 作用总结:    

          a.1、接口可以描述事物不属于继承体系中的扩展的功能;

          a.2、通过多态的方式使用接口,可以提高程序的扩展性;

          a.3、接口实现了java中的多继承;

        b. 使用接口定义规则

          规则,就是规范,是一种约定;

      

    五、接口和抽象类的区别

      1. 接口和抽象类的区别   

         a. 从声明上:

          抽象类是一个类,使用class声明;还需要使用关键字abstract修饰;

          接口不是一个类,使用interface声明;

        b. 从能够书写的成员上看:

          抽象类是一个类,可以书写类中可以书写的成员,和抽象函数;

          接口只能书写成员变量和抽象函数,而且修饰符是固定的;

        c.从有无构造函数上看:

          抽象类必须有构造函数;

          接口没有构造函数

        d.从作用上看:

            抽象类是父类,用来描述所有子类的共性信息的,只是描述的有些功能是不具体的;

            接口是用来描述不属于继承体系的扩展功能的;还可以定义规则;

        e.继承关系上:

          抽象类和类之间是继承关系,只支持单继承和多重继承;

         接口和类之间是实现关系,一个实现类可以实现多个接口;

         接口和接口之间是继承关系,可以多继承和多重继承;

      2.接口和抽象类的使用练习   

        需求:描述手机和电脑,都有开机、关机和可以玩游戏的功能;

        

        

     1 //表示可以玩游戏的接口
     2 interface PlayGame
     3 {
     4     //表示具有玩游戏的功能
     5     public void palyGame();
     6 }
     7 //表示电子产品
     8 abstract class ElecPro
     9 {
    10     //所有的电子产品都可以开机关机,不同的电子产品开关机的实现不同
    11     //所以要是抽象的
    12     public abstract void open();
    13     public abstract void close();
    14 }
    15 //描述手机
    16 class Phone extends ElecPro implements PlayGame
    17 {
    18     public void open(){
    19         System.out.println("手机开机");
    20     }
    21     public void close(){
    22         System.out.println("手机关机");
    23     }
    24     public void palyGame(){
    25         System.out.println("手机玩游戏");
    26     }
    27 }
    28 //描述电脑
    29 class Computer extends ElecPro implements PlayGame
    30 {
    31     public void open(){
    32         System.out.println("电脑开机");
    33     }
    34     public void close(){
    35         System.out.println("电脑关机");
    36     }
    37     public void palyGame(){
    38         System.out.println("电脑玩游戏");
    39     }
    40 }

          

          

          

      

        

          

        

        

      

        

         

     

        

        

     

  • 相关阅读:
    设计模式 ( 十七) 状态模式State(对象行为型)
    Intellij13 IDEA常用快捷键 (mac 10.5 +),优化,使用出现的问题汇总
    Web服务器及Web应用服务器
    阮一峰的网络日志
    双击退出的实现
    完成3DM以后的总结(2).Xutils的简单使用
    完成3DM以后的总结(1).PullToRefresh
    软考之路之j2se总结
    2013-2014年终总结
    牛腩新闻发布系统之获取IP
  • 原文地址:https://www.cnblogs.com/Kubility123/p/7599424.html
Copyright © 2020-2023  润新知