zoukankan      html  css  js  c++  java
  • java——抽象类、接口、二者区别

    抽象类:

      抽象方法:不包含方法体的方法为抽象方法,抽象方法必须使用abstract关键字来修饰:

        abstract void method();

      抽象类:当一个类中包含了抽象方法时,该类必须使用abstract关键字来修饰。抽象类可以不包含抽象方法,但是有抽象方法的类一定是抽象类。

    abstract ABC {
         public abstract String getXXX();   
        ...  
    }

      抽象类不能创建一个类的对象。

      子类必须实现抽象类定义的抽象方法。

      抽象类不能被关键字final修饰(final关键字修饰的类不可被继承), abstract不能和static(static是静态的,而abstrict是动态的,必须通过类继承或接口实现来动态重写abstrict方法)、private(private修饰的方法只能在类中调用,重写时是访问不到这些方法和属性的)、final(final关键字修饰的方法不可被重写)、native并列修饰同一方法。

       举个栗子:

    abstract class Goods {
        public Goods(String name, double price, double num) {
            this.name = name;
            this.price = price;
            this.num = num;
        }
        public String getName() {
            return this.name;
        }
        public double getPrice() {
            return this.price;
        }
        //返回总消费
        public abstract double getTotalPrice();
        //输出商品信息
        public abstract String toString();
        //同一包中以及不同包中该类的子类,如果用private 那子类就不能用这个属性了
        protected String name;
        private double price;
        protected double num;
    }
    class AmountGoods extends Goods{
        public AmountGoods(String name, double price, int amount) {
            super(name, price, amount);
        }
        //自己特有的方法
        public int getAmount() {
            return (int)this.num;
        }
        public double getTotalPrice() {
            return this.getPrice() * this.num;
        }
        public String toString() {
            return this.getName()+"	"+this.getPrice()+"	¥/个";
        }
    }
    class GravityGoods extends Goods{
        public GravityGoods(String name, double price, double gravity) {
            super(name, price, gravity);
        }
        public double getTotalPrice() {
            return this.getPrice()*this.num;
        }
        public String toString() {
            return this.name+"	"+this.getPrice()+"	¥/斤";
        }
        public double getGravity() {
            return this.num;
        }
    }
    public class AbstractDemo{
        public static void main(String[] args) {
            AmountGoods goods1 = new AmountGoods("苹果", 2.5, 5);
            GravityGoods goods2 = new GravityGoods("草莓", 10, 8);
            System.out.println(goods1.toString()+"	 数量"+goods1.getAmount()+"	 计价"+goods1.getTotalPrice());
            System.out.println(goods2.toString()+"	 数量"+goods2.getGravity()+"	 计价"+goods2.getTotalPrice());
        }
    }

    接口:

      1.如果一个抽象类的所有方法都是抽象的,则可以将这个类用另外一种方式来定义,即接口。

      2.接口是由常量抽象方法组成的特殊类,是对抽象类的进一步抽象,接口的目的是为了实现多继承。

      3.用interface来声明。

      4.要继承接口的类需要用implements关键字,需要注意的是一个类实现一个接口,必须给出接口中所有方法的实现,如果不能实现某方法,也必须写出一个空方法。

      5.一个类在继承另一个类的同时还可以实现接口,此时extends关键字必须位于implements关键字之前。

    抽象类实现接口:

      在接口中没有实现的方法必须声明为抽象方法。

    派生接口:

      一个接口可以派生一个新的接口,该接口称为拓展接口。

      接口之间的继承用extends。

    Comparable接口:

      Arrays类中的sort方法可以对数组进行排序,可以通过实现Comparable实现想要的排序。

    下面是上述几个接口的例子

    package follow_pack;
    
    import java.util.Arrays;
    
    public class exp {
        public static void main(String[] args) {
            RectangleSort[] rect = new RectangleSort[10];
            for(int i = 0; i<10; i++) {
                rect[i] = new RectangleSort(i+1,(10-i+0.5)*0.5);
            }
            System.out.println("排列前:");
            for(RectangleSort e: rect)
                System.out.println("边长为:	"+e.getRlong()+"	"+e.getRwidth()+"	 面积 = 	"+e.getArea());
            Arrays.sort(rect);
            System.out.println("排序后:");
            for(RectangleSort e: rect)
                System.out.println("边长为:	"+e.getRlong()+"	"+e.getRwidth()+"	 面积 = 	"+e.getArea());
        }
    }    
    // 定义一个接口
    interface Shape{
        public double getArea();
        public double getSideLong();
        public static final double PI = 3.14;
    }
    // 定义一个类 实现接口
    class Rectangle implements Shape{
        public Rectangle(double l, double w) {
            rlong = l;
            rwidth = w;
        }
        public void setRlong(double l) {
            rlong = l;
        }
        public void setRwidth(double w) {
            rwidth = w;
        }
        public double getRlong() {
            return rlong;
        }
        public double getRwidth() {
            return rwidth;
        }
        public double getArea() {
            return rlong*rwidth;
        }
        public double getSideLong() {
            return (rlong+rwidth)*2;
        }
        private double rlong;
        private double rwidth;
    }
    // 抽象类实现接口
    abstract class Polygon implements Shape{
        protected int sidenumber;
        public void setSideNumber(int sn) {
            sidenumber = sn;
        }
        public int getSideNumber() {
            return sidenumber;
        }
        public abstract double getArea();
        public abstract double getSideLong();
    }
    // 派生接口
    interface PolygonInterface extends Shape{
        public void setSideNum(int sn);
        public int getSideNum();
    }
     // Comparable接口
    class RectangleSort implements Shape, Comparable<RectangleSort>{
        public RectangleSort(double l, double w) {
            rlong = l;
            rwidth = w;
        }
        public void setRlong(double l) {
            rlong = l;
        }
        public void setRwidth(double w) {
            rwidth = w;
        }
        public double getRlong() {
            return rlong;
        }
        public double getRwidth() {
            return rwidth;
        }
        public double getArea() {
            return rlong*rwidth;
        }
        public double getSideLong() {
            return 2*(rlong + rwidth);
        }
        // 声明compareTo方法
        public int compareTo(RectangleSort other) {
            if(this.getArea()<other.getArea())
                return -1;
            else if(this.getArea()>other.getArea())
                return 1;
            else
                return 0;
        }
        private double rlong;
        private double rwidth;
    }

     接口中定义常量:

      任何接口中定义的常量必须为public static final类型,因此java允许省略此类修饰符。

    Cloneable接口:

      clone()方法是object类的一个protected方法,因此用户不能直接调用该方法。clone()方法默认实现浅拷贝。

      如果一个程序要进行克隆处理,就要继承这个接口。

    public class Audience implements Cloneable{
        //声明构造方法
        public Audience(String name) {
            this.name = new StringBuffer(name);
            id = flag;
        }
        public void setName(String name){
            StringBuffer temp = new StringBuffer(name);
            if(this.name != null) {
                this.name.replace(0, name.length(), name);
            }else {
                this.name = temp;
            }
        }
        public String toString(){
            return "name:	" + name +"	id:	" +id;
        }
        //初始化语句块,如果不加{}会怎样?
        {
            flag++;
        }
        //浅拷贝,这种重写clone()只是把clone变成了public
    //    public Object clone() throws CloneNotSupportedException{
    //        return (Audience)super.clone();
    //    }
        //深拷贝,和浅拷贝不同的是,这个clone返回的对象是这个方法中新建的一个对象,占用了一块新的内存单元
        public Object clone() {
            Audience object = null;
            try {
                //完成数值类型变量的值传递,也就是说先把被拷贝对象的值赋值给新对象。
                object = (Audience)super.clone();
            }catch(CloneNotSupportedException e){
                System.out.println(e.toString());
            }
            //因为是au1.clone(),所以name是au1.name,也就是“quanquan”
            //当执行了au2.setName()之后au2.name里面就变成了“duoduo”
            //因为string不是基本数据类型,
            //上一步已经把属于基本数据类型的变量复制到一个新的内存单元了
            //所以这一步就要把不是基本数据类型的string类型变量放到一个新的内存单元中去
            object.name = new StringBuffer(name);
            return object;
        }
        private StringBuffer name;
        private static int flag=0;
        private int id;
        public static void main(String[] args) {
            Audience au1 = new Audience("quanquan");
            Audience au2 = null;
            au2 = (Audience)au1.clone();
    //        try{
    //            au2 = (Audience)au1.clone();
    //        }catch(CloneNotSupportedException e){
    //            System.out.println(e.toString());
    //        }
            
            System.out.println(au1.toString());
            System.out.println(au2.toString());
            au2.setName("duoduo");
            System.out.println(au1.toString());
            System.out.println(au2.toString());
            
        }
        
    }

     二者区别:

      抽象类:

        抽象类不能创建类对象。

        表示一种继承关系。

        一个类只能继承一个父类。

        可以有自己的变量,也可以由非abstract方法。

        变量默认为default,变量值可以再子类中重新定义,重新赋值。

      接口:

        接口的access为public或default。

        接口不是类,不能创建接口对象。

        表示一种契约关系。

        一个类可以实现多个接口。

        只允许定义常量,所有方法都是public abstract类型并且可以省略。

        接口定义的变量默认是public static final类型,可以省略但是必须给定初值,实现类中不能重新定义,也不能改变其值。

  • 相关阅读:
    ES6 新特性
    基于.NET平台常用的框架整理
    你可能不知道的一些JavaScript 奇技淫巧
    js中apply方法的使用
    数据库中字段类型对应C#中的数据类型
    C# Socket SSL通讯笔记
    Media Types
    JS使用模板快速填充HTML控件数据 --- 自己写组件(0)
    FastDFS的配置、部署与API使用解读(8)FastDFS多种文件上传接口详解
    FastDFS的配置、部署与API使用解读(7)Nginx的FastDFS模块
  • 原文地址:https://www.cnblogs.com/gaoquanquan/p/9703768.html
Copyright © 2011-2022 走看看