黑马程序员-java基础加强_面向对象

来源:互联网 发布:阿里云推荐码2017 编辑:程序博客网 时间:2024/06/09 23:48

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

一、什么是抽象类,什么是抽象方法

        抽象类:用abstract来修饰的类
        抽象方法:用abstract来修饰的方法

        抽象方法作用:它只是定义具有的行为,而没有具体的方法体
                      简单说,抽象方法中有方法声明,而没有执行内容
        如果一个类中有抽象方法,那么这个类必须是抽象类.
        如果一个类继承了抽象类,那么子类必须将父类中的抽有抽象方法进行重写.
        抽象特点:
            1.抽象类用abstract修饰  抽象方法也是用abstract来修饰
            2. 如果一个类中有abstract方法,那么这个类也必须是abstract类
            3.子类如果继承抽象类,那么必须将父类中的所有抽象方法重写.
            4.抽象类不可以实例化,不可以去new.抽象类的作用就是让子类继承进行重写.

                因为抽象类中的抽象方法没有方法体,得到这个类的对象调用这个上方法没意义,
                所有不允许实例化抽象类
        
        示例
            宝马车
            奔驰车

            行驶行为

            对于宝马与奔驰都有行驶的方法,我们可以将其进行抽取,形成一个Car类,这个类中
            有一个行驶的方法,这个方法可以让宝马,奔驰进行重写。

            但是在Car类中,这个行驶的方法需要具体的方法体吗?

            我们发现Car类中的run方法它的具体的内容其实没有什么太大作用,但是这个方法
            是需要的,它用来让子类进行重写。

            对于这种情况,java中可以通过抽象类,抽象方法的概念来解决。
            Demo2代码:

class Demo2 { public static void main(String[] args) { //Bmw bmw=new Bmw(); //bmw.run(); //Car c=new Car();//不可以实例化 }}/* 宝马车 奔驰车 行驶行为 对于宝马与奔驰都有行驶的方法,我们可以将其进行抽取,形成一个Car类,这个类中 有一个行驶的方法,这个方法可以让宝马,奔驰进行重写。 但是在Car类中,这个行驶的方法需要具体的方法体吗? 我们发现Car类中的run方法它的具体的内容其实没有什么太大作用,但是这个方法 是需要的,它用来让子类进行重写。 对于这种情况,java中可以通过抽象类,抽象方法的概念来解决。*/abstract class Car { abstract void run();}class Bmw extends Car{ void run(){ System.out.println("宝马车在行驶"); }}class Benz extends Car{ void run(){ System.out.println("奔驰车在行行驶"); }}

        抽象类的好处:
        
            1.将子类对象共性的行为进行抽取,让子类在继承时,必须进行重写。
              父类中只有行为的声明,而没有具体的实现。

            2.抽象类进行了规则的制定,有强制作用。

二、抽象的使用
    
    1.什么时候使用抽象

        多个对象具有共同的行为,但是行为的实现不同,
        我们可以将这些行为进行抽取,但不抽取具体的实现,
        这时就可以使用抽象方法。
    
        如果一个方法是抽象的,它所在的类必须是抽象类。    
        
    2.抽象的细节
        1.抽象类中是否可以没抽象方法   java.awt.* 包下的类有这样的操作.

        2.抽象类是否可以继承  1.抽象类   2.普通类
            可以继承普通类

            可以继承抽象类,如果子类继承了抽象类,并且没有对抽象方法进行重写,那么这个子类也是一个抽象类

        3.抽象类有没有构造方法
            
            可以有构造。抽象类的作用是让子类继承,构造方法是让子类进行初始化。
            抽象类也是一个类,具有类的特征,所有也要有构造方法,但是它的作用不是为了
            进行自己的初始化,是为子类提供初始化

        4.abstract与其它修饰符关系

            final:它的作用  修饰类代表不可以继承  修饰方法不可重写
            abstract修饰类就是用来被继承的,修饰方法就是用来被重写的。
            final与abstract不能共存

            static static修饰的方法可以用类名调用,
                对于abstract修饰的方法没有具体的方法实现,所有不能直接调用,
                也就是说不可以与static共存.

            private
                private修饰的只能在本类中使用,
                abstract方法是用来被子类进行重写的,有矛盾
                所有不能共存.
        
        


  三、  接口
    
        简单理解成是一个特殊的抽象类
        如果一个抽象类中的方法全是抽象方法,那么你就可以将其声明成一个接口。

        接口中的所有方法都是抽象方法.
        声明类
        class 类名{
            属性
            方法
        }
        声明接口

        interface 接口名{
            属性
            抽象方法
        }

        接口中的所有属性 默认的修饰符是  public static final
        接口中的所有方法 默认的修饰符是  public abstract   
        
        接口中无论是属性还是方法,它默认的权限都是public

        接口与类之间有什么关系

        1.抽象类是用来被继承的,可以将抽象类中的抽象方法重写

        2.接口中的方法都是抽象的,也就是说,需要将接口中的方法都进行重写。
          类与接口之间存在 实现的关系.

          一个类要想实现接口用到另个一个关键字   implements

            class 类名 implements 接口名{
            
            }

            当一个类实现了接口,那么必须将接口中的所有方法进行重写。

    接口思想

        电脑内存槽

        笔记本的usb接口

        这些都是标准

        
        接口有两种概念

            1.java中的interface

            2.公共的规则

            API 应用程序接口

          
    
  四、  多实现

        java中通过接口来完成多继承

        1.为什么可以有多实现
            接口中的方法都是抽象方法,也就是说只定义了方法的声明,而没有具体的实现
            那这时候我们就可以进行多实现。不会引起混淆。
                一个类可以去实现多个接口

        格式  class 实现类 implements 接口1,接口2,...
        

        接口与父类它们都完成什么功能

            父类 定义的是共公的行为
            接口 扩展的行为
    接口与抽象类的区别
        
        1.类与抽象类之间存在的是继承关系,并且是一种单继承
          类与接口之间存在的是实现关系   可以多实现

         2.抽象类是继承  is a  也就是说父类中定义的是子类中公共的行为
           接口是实现    like a  也就是接口中定义的是子类的扩展功能
          
        3.抽象类中有抽象方法,也可以存在实例方法,可以让子类直接使用
          接口中都是抽象的方法,要想使用,只能去做个实现类去实现接口,使用实现类中的方法。
        接口与抽象类相同点
            1.接口与抽象类都是将子类中共性的内容将上抽取得到的。
            2.抽象类不可以实例化,接口也不可以实例化  
                简单说,接口与抽象类都不能new

        1.类与类之间的关系
            
            继承关系  extends

            子类继承父类中的所有成员。
        
        2.类与接口的关系

            实现关系 implements

                实现类继承了接口中的属性,重写了接口中的所有方法.

        3.接口与接口的关系

            继承  extends   更正确的说  接口的扩展

            子接口继承了父接口中的所有成员

        
        如果实现类是一个抽象类,那么可以不用重写接口中的方法。



    五、多态  某一类事物的多种存在形态。
              同一种行为表现出不同的状态
           多态可以存在的前提:  
1.子类与父类  继承    ,2.接口与实现类  实现
                父类 引用 = new 子类    父类引用指向子类对象
                接口  引用= new 实现类   接口回调
            需要进行重写                

        多态的作用与好处
            提高了代码复用性与扩展性,增加了后期代码的可维护性
            前期可能不知道具体的子类(实现类)是怎样实现的,但是我们可以在父类,接口中
            定义这些行为,让子类与实现类去实现。使用时使用的是父类的引用或者接口的引用,
            这样它的扩展性与可维护性增强

/* 多态示例*/class Test7{ public static void main(String[] args) { Car c=Car4s.getCar(Benz.BENZ_ID); c.run(); }}/* 宝马车 奔驰车 车有行驶*///车的4S店class Car4s{ //售车 public static Car getCar(int carId){ Car c=null; //多态 if(carId==Bmw.BMW_ID){ c=new Bmw(); } if(carId==Benz.BENZ_ID){ c=new Benz(); } return c; }}interface Car{ void run();}class Bmw implements Car{ public static final int BMW_ID=1; public void run(){ System.out.println("bmw run....."); }}class Benz implements Car{ public static final int BENZ_ID=2; public void run(){ System.out.println("benz run..."); }}


        存在的弊端

            存在问题:在子类或实现类中独有的行为不可能通过父类引用或者接口的引用去调用。


    多态的细节

        1.实例方法
            编译时:查看父类(父接口)中是否存在调用的方法
            运行时: 调用的是子类(实现类)中重写的方法

        2.实例属性
            编译时:查看父类(接口)中是否存在这样的属性
            运行时: 得到的是父类(接口)中的实例属性.

        3.类方法
            编译时:查看父类(父接口)中是否存在调用的方法
            运行时: 调用的是父类中的类方法
          
   多态中注意的细节:   多态中类型转换
       
        引用类型转换问题

        1.自动转换(向上转型)
            Animal a=new Cat();
            a是Animal类型   new Cat()是Cat类型
            将Cat类型的值赋给了Animal类型

            其实就是向上转换型,原来是子类类型,向上转换成父类类型
            这种转换型可以存在的条件必须存在(继承,实现)
        2.强制转换(向下转型)

            Animal a=new Cat(); a是父类的类型,
            不可以直接调用子类中独有的行为,
            那么想要调用,可以将a向下转换型(将其强制转换成子类类型)

        无论是自动还是强制转换必须有前提条件:这种转换型可以存在的条件必须存在(继承,实现)

        为什么向下转换:想要调用子类中独有的方法.

    模板方法模式
       
        将方法进行隐藏或者说不过多的暴露行为
        提高代码的复用性
           
        我们在设计这个模型时发现 start点火    stop 停止  引擎转动这三个行为是变化的,需要由具体子类
        来实现,行驶这个行为是固定,所有子类中都一样。我们可以在父类中定义,将其实现,直正执行时,
        还是去执行具体的子类中的行为.
        这种方式也是设计模式中的一种,模板方法模式.
           
       模板模式代码:

//创建悍马模型         abstract class HM         {             //打火             abstract void start();             //停止             abstract void stop();             //引擎转动             abstract void yinQingBoom();             //行驶             void run(){                    //真正调用时还时执行子类中的重写的方法                 this.start();                 this.yinQingBoom();                 this.stop();             }         }         class H1 extends HM         {            //打火             void start(){                 System.out.println("H1 打火");             }             //停止              void stop(){                 System.out.println("H1 停止");             }             //引擎转动              void yinQingBoom(){                 System.out.println("H1 引擎转动");                       }         class H3 extends HM         {             //打火             void start(){                                System.out.println("H3 打火");             }             //停止              void stop(){                 System.out.println("H3 停止");             }             //引擎转动              void yinQingBoom(){                 System.out.println("H3 引擎转动");             }                    }


原创粉丝点击