java 从零开始,学习笔记之基础入门<抽象类_接口_多态>(十三)

时间:2023-02-24 20:37:00

 抽象类_接口_多态

 Abstract关键字 表示的是抽象类

他可以修饰一个类或者方法

如果它用来修饰一个类,表示此类是一个抽象类

如果它用来修饰一个方法则表示此方法为一个抽象方法

抽象类:

语法格式:访问修饰符+abstract+class+类名{

抽象方法; 普通方法 

例如:

 package com.ibm.abstractes; 

public abstract class AbstractesDemo {

  }

   

抽象类不能被实例化,也就是说抽象类不能被new关键字来创建他的对象

 

抽象方法:

     用abstrat来修饰的方法,方法没有方法体

语法格式

    访问修饰符+abstrat+返回值类型  方法名(参数列表);

public abstract class AbstractDemo {

    public abstract String show();

   

    public abstractint show1(int m ,int n);

}

 

抽象方法只有方法的生命,没有具体的方法的实现。

抽象类中既可以包含抽象,也可以包含普通方法,如果抽象类中没有抽象方法,那么抽象类就没有存在的必要性。

一下任意条件满足时,类必须定义成抽象类:

     1 此类中含有一个或者一个以上抽象方法

     2 类继承了父类中的抽象方法,并且至少有一个抽象方法没有实现

            * 抽象类可以被继承  如果一个普通类继承了一个抽象类,那么需要在普通类中实现抽象类中的所有抽象方法

            * 如果一个类继承了一个抽象类,并且没有被继承类的所有抽象方法,那么此类一定是抽象类,一个抽象类可以继承另外一个抽象类,也可以多级继承,但是一个抽象类只能继承一个抽象类

     3  类实现了某个接口,但是没有全部实现接口中的方法

            * 接口中的方法全部都是抽象方法

            * 如果一个普通类实现了某个接口,就需要实现接口中的所有方法,如果没有全部实现接口中的方法,那么此类一定是一个抽象类

抽象类不能够直接实例化对象,如果需要实例化对象,那么必须通过之类来实例化

                 父类 父类对象=new 子类构造器();

 

计算买一张汽车票、火车票、飞机票的票价的算法:

    汽车票:票价+保险

    火车票:票价(如果是学生/2  成人全票)+保险

    飞机票:票价+

 

package com.ibm.abstrates;

 

public abstract class SaleTicket {

   

    /**

     * @param money票价

     * @param save 保险

     * @return

     */

    public abstract float saleCar(float money,float save );

   

    public abstract float saleTrain(float money,String typeP,float save);

   

    public abstract float saleFly(float money,float otherMoney,float otherMoney1,float save);

 

}

 

package com.ibm.abstrates;

 

public class SaleClient extends SaleTicket{

 

    public float saleCar(float money,float save) {

       //TODO Auto-generated method stub

       return money+save;

    }

 

    @Override

    public float saleTrain(float money, String typeP, float save) {

       float f = 0.0f;

       if(typeP.equals("成人")){      

           f = money+save;

       }

       if(typeP.equals("小孩")){

           f = money/2+save;

       }

       return f;

    }

 

    @Override

    public float saleFly(float money, float otherMoney,float otherMoney1,

           float save) {

       return money+otherMoney+otherMoney1+save;

    }

 

}

package com.ibm.abstrates;

 

public class SaleTest {

    public static void main(String[] args) {

       //抽象类不能被实例化

       //SaleTicketst = new SaleTicket();

      

       SaleClient sc = new SaleClient();

       System.out.println(sc.saleCar(36, 1));

       //抽象类中只有方法的生命,没有具体的实现,具体的实现方法在其子类中实现

//     SaleTicket st = new SaleClient();//将子类的对象赋给父类的引用,调用方法执行的时候是子类中的方法

       SaleTicket st = null;

       SaleClient sc1 = new SaleClient();

       st=sc1;

       System.out.println(st.saleCar(36,1));

    }

 

}

 

 

一个抽象类可以继承另一个抽象类,那么抽象类中的方法都会被继承过来

可以将一个子类的对象赋给父类的引用,通过父类的对象调方法,指向的是类中的抽象方法,

但是执行的是子类的方法。

 

模式设计模式:

在父类中定义的一个算法的骨架,不具体的实现算法是怎么做,而是在其子类中体的实现算法的实现细节。那么在父类中定义的方法就是抽象方法,在其子类那个实现的方法就是普通方法

 

 

v  例如,银行计算利息,都是利率乘以本金和存款时间,但各种存款方式计算利率的方式不同,所以,在账户这个类的相关方法里,只搭出算法的骨架,但不具体实现。具体实现由各个子类来完成。

 

abstract class LoanAccount{

       //利息,本金

       private double Interest, Fund;

       public double calculateInterest(){

           //取得利率

           double interest=getInterestRate();

           //计算利息的算法:本金*利率,

          //但是利率的算法实现并没有在这个类中实现

           Interest=getFund()*getInterestRate();

           return Interest;

       }    

     /**不同的存款类型有不同的利率, 因此,不在这个父类中实现利率的计算方法,而将它推迟到子类中实现*/

       protected abstract double getInterestRate();

}

}

 

接口:是抽象方法与常量的集合。也就是说接口中只能存在抽象方法和常量,不能够存在除了抽象方法以外的其他普通方法。

接口可以看做是一个比抽象类更加抽象的类。

接口中也只有方法的生命,没有具体的方法的实现。

接口中只包含常量或者抽象方法.

 

接口的语法格式:

    访问修饰符+interface+接口名{

  //常量 :访问修饰符 +static +final +数据类型 + 常量名=常量值

               注意: Java编码规范中,常量名必须都大写

  //抽象方法

}

      *@authorAdministrator

 * 接口是比抽象类更加抽象的类

 *  抽象类可以有抽象方法和普通方法而接口中则只能有抽象方法

 *  接口中只能存在常量,不能存在变量

 *  一个类用implements关键字来实现一个接口,

 *  在实现来中实现接口中所有没实现的方法

 *  接口可以看着多个未实现方法的集合

 *  一个类能否实现多个接口?

 *  一个类可以实现多个接口,

 *   但是该类要将多个接口中的所有未实现的方法实现一遍

 *   接口可以继承一个接口么?

 *   接口可以继承一个或者多个接口,是多继承的

 *   继承多个接口用extends关键字,接口与接口之间用“,”号分开

 

package com.ibm.interfaces;

 

public interface InterfaceDemo {

    //在接口中可以定义常量不能定义变量

    //在接口中只能有抽象方法不能有普通方法

   

   

    public staticfinal StringNAME="Ibm";

   

    public abstract void show();

    //Stringstr;//不能定义

    //public void show2(){}//不能定义

   

   

 

}

 

 

一个接口可以继承另外一个接口,继承的关键字也是extends,并且和类不同的是:一个接口可以继承多个接口。

如果一个接口继承了多个接口,那么就继承了接口中的所有方法,如果一个类实现该接口,那么此类就应该实现所有接口中的所有方法

一个类实现多个接口采用implements关键字,实现多个接口,接口与接口直接用“,”分开

如果一个类实现了一个或者多个接口那么该类就必须实现接口中所有没有实现的方法。

public class 类名 implements 接口名1,接口名2,接口名3{

 

}

多个类可以同时实现一个接口

一个类可以同时实现一个或者多个接口

如果一个类同时 实现了多个接口,那么该类就应该重写所有接口中的抽象方法。

package com.ibm.interfaces;

 

public class Client implements FatherInterface,GrandFatherInterface{

 

    @Override

    public void makeMoney() {

       //TODO Auto-generated method stub

      

    }

 

    @Override

    public String getName() {

       //TODO Auto-generated method stub

       return null;

    }

 

    @Override

    public void show() {

       //TODO Auto-generated method stub

      

    }

 

}

 

 

为什么要使用接口?

1        隐藏了具体的方法的实现细节

2        提高了程序的扩展性

3        方便代码维护

 

 

 

多态

一种形态多种表现形式。

v  在Java中,对象变量是多态的。一个类型为Aclass的变量既可以指向类型为Aclass的对象,又可以指向Aclass的任何子类的对象

v  以多态的形式来传递参数,增强了参数类型的灵活性

v  一个对象只能有一种确切的数据类型

v  一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法

 

在类与类的继承中呢,传递的如果是一个父类的对象,则访问时,只能访问到父类中有的方法,在子类中新增加的方法则访问不到

 

将具体的实现类的对象赋给声明的接口的对象,通过接口的对象指向的是接口中的抽象方法,但实质上调用的是实现类中实现接口的方法

 

 

package com.ibm.Polymorphisms;

 

public interface Person {

   

    public abstract void run();

      

    publicabstract void eat();

   

    public abstract void sleep();

}

 

package com.ibm.Polymorphisms;

 

public class Girl implements Person{

 

    @Override

    publicvoid run() {

       //TODO Auto-generated method stub

       System.out.println("我是girlrun方法");

    }

}

 

package com.ibm.Polymorphisms;

 

public class Boy implements Person{

 

    @Override

    public void run() {

       //TODO Auto-generated method stub

       System.out.println("我是boyrun方法");

    }

}

package com.ibm.Polymorphisms;

 

public class Test {

    //有一个方法来打印出对应的某一个对象的方法

//  public void show(Girl g){

//     g.run();

//  }

// 

//  public void show(Boy b){

//     b.run();

//  }

// 

//  public void show(Man m){

//     m.run();

//  }

   

    public void show(Person p){

       p.run();

    }

   

    public static void main(String[] args) {

      

       new Test().show(new Girl());

       new Test().show(new Boy());

       new Test().show(new Man());

    }

 

}

 

 

对象造型(casting)

所谓对象造型就是对象间的相互转换,但是相互转换的对象之间要存在关系

对象造型分二类:

package com.ibm.casting;

 

public class Father {

 

}

 

 

package com.ibm.casting;

 

public class Sonextends Father{

 

}

 

 

    自动造型:由小转大  由子类转父类

       //自动造型也成隐式转换

       //对象的造型就是对象的相互转换,在此处就是FatherSon类的相互转换

       //自动造型将子类的对象转换成父类

//         Father f = new Son();

//         System.out.println(f);

 

    强制造型:由大转小  由父类转子类

       //强制造型将父类对象转换成子类

       //如果你想强制将父类对象转换成子类的对象,那么你必须先将子类的对象转换成父类的对象

       //再将转换之后的父类对象强制转换成子类对象

       //如果直接将父类强制转换成子类对象,会报类转换异常

           Father f = new Son();

           Son s =  (Son) f;

           System.out.println(s);

 

instanceof

// instanceof 关键字用来判断创建的对象是否是某一个类的对象

       //1.通过隐式转换将子类对象转换成父类对象,转换之后的对象

      

//     Father f = new Son();

//     Father f = null;

//     Son s = new Son();

//     f = s;

//     System.out.println(f instanceof Father);

//     System.out.println(f instanceof Son);

//    

//     Son s1 = (Son)f;

//     System.out.println(s1 instanceof Son);

//     System.out.println(s1 instanceof Father);