zoukankan      html  css  js  c++  java
  • 大数据学习--day11(抽象类、接口、equals、compareTo)

    抽象类、接口、equals、compareTo

    什么是抽象方法  ?

        区分于正常的方法  
        1.使用了 abstract 修饰符 
            该修饰符修饰方法 则该方法就是抽象方法 该修饰符修饰类 , 则该类就是抽象类
        2. 没有方法体 
        3. 小括号之后用 分号 作为结尾 

    什么是抽象类  ?

            abstract 修饰的类就是抽象类  
            抽象类可以认为是 部分抽象的类 
            后期还有 完全抽象
            这里的抽象 指的是内部中无法描述的部分  -> 抽象方法

    抽象类 可以包含什么成员  ?

            1. 属性
            2. 静态字段 类变量 
            3. 构造器
            4. 正常方法 
            5. 静态方法
            6. 抽象方法

    抽象类的特性  

            1. 必须 abstract 修饰
            2. 可以有构造器 , 但是不能 实例化对象  不能     new 构造器([实参]);
            3. 抽象类也是类  比较特殊的一种类  , 可以继承正常类 也可以继承抽象类    单继承
            4. 抽象类可以被继承 但是继承抽象类 和 继承普通的类有所不同
            5. 抽象类中 可以没有抽象方法

    抽象类的应用场景

            经常作为底层的抽象基类存在 
            例如在集合家族中  , 扮演了 接口(完全抽象) 和 正常类 中间的 缓冲环节
            抽象类是 完全抽象  -> 部分抽象  -> 正常类 , 中间的过渡

    接口

    接口中 可以包含什么成员  ?    

            1. 公共的public  静态的static  常量final
                不写的话 默认就是 public static final 修饰的
                如果更改权限 那么报错
            2. 公共的抽象方法
                不写的话 默认就是 public abstract 修饰的
                规定其他的修饰符 例如 static final 会报错

    接口的特性 : 

            1. 接口不可以实例化对象
            2. 接口可以继承接口 接口是多继承 , 多个父接口用 逗号 隔开  关键字仍然用 extends
                    接口继承接口之后  会继承父接口的抽象方法 , 即继承了 规范和要求
            3. 类 可以实现接口 , 实现和继承会有所不同
                    继承指的是 类继承类 , 接口继承接口     extends 
                    实现指的是 类 实现 接口    implements
                    类实现接口之后 , 接口类型也是类的父类型 , 也可以方法重写  , 也可以多态
                    类和接口是多实现的 , 一个类可以实现多个接口  , 多个父接口用逗号隔开    
            4. 接口是引用数据类型 接口类型引用可以存储子类对象 

    抽象类 和 接口的 异同

    你选择使用接口和抽象类的依据是什么?

    接口和抽象类的概念不一样。
    接口是对动作的抽象,抽象类是对根源的抽象。
     抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。 人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它. 
    所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。
     
     当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。 
     抽象类的功能要远超过接口,但是,定义抽象类的代价高。
    因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的 所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的。
     
     下面看一个网上流传最广泛的例子:门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念:
    abstract class Door {
        public abstract void open();
        public abstract void close();
    }

    或者:

    interface Door {
        public abstract void open();
        public abstract void close();
    }

    但是现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?下面提供两种思路:

      1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但是有的门并不一定具备报警功能;

      2)将这三个功能都放在接口里面,需要用到报警功能的类就需要实现这个接口中的open( )和close( ),也许这个类根本就不具备open( )和close( )这两个功能,比如火灾报警器。

      从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口

    interface Alram {
        void alarm();
    }
     
    abstract class Door {
        void open();
        void close();
    }
     
    class AlarmDoor extends Door implements Alarm {
        void oepn() {
          //....
        }
        void close() {
          //....
        }
        void alarm() {
          //....
        }
    }

    equals、Comparable

    两个类比较,比较的是地址

    重写equals方法,每个属性比较相等。要比较大小,实现接口。

    public class Person implements Comparable{
        public String name;
        private int age ;
        private boolean sex;
        public Person() {
            // TODO Auto-generated constructor stub
        }
        public Person(String name , int age, boolean sex) {
            super();
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public boolean isSex() {
            return sex;
        }
        public void setSex(boolean sex) {
            this.sex = sex;
        }
        
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
        }
        
        
        
        /**
         * 如果有属性是引用数据类型 , 一定不能 == 来比较
         * 而是调用属性对象的 equals 方法 
         */
        
        /**
         *     instanceof    关系运算符  
         *  使用格式 : 
         *      对象 instanceof 类名 ; 
         *  返回 布尔值
         *  如果 对象是该类的对象 , 那么返回true  反之false
         *  
         */
        /**
         * 基本数据类型强转 : 可能会丢失数据
         * 引用数据类型强转 : 可能会有类型不匹配异常  java.lang.ClassCastException
         *                       如果没有继承关系 不能强转
         */
        
        @Override
        public boolean equals(Object obj) {
            if( this == obj)
                return true;
            
            // 判断 obj 是本类对象
            if( !(obj instanceof Person) )
                return false;
                
            // 引用数据强转  经过判断之后可以放心的强转了
            Person p = (Person)obj;
            
            // 接下来是 具体的判断是否相等的 业务逻辑
            if( this.age == p.age)
                if(this.sex == p.sex)
                    if(this.name.equals(p.name)) 
                        return true;
            
            return false;
        }
        
        
        /**
         * 1. 判断参数是不是本类对象
         * 2. 书写具体的比较规则
         */
    //    @Override
    //    public int compareTo(Object o) {
    //        if( !(o instanceof Person) )
    //                return 0 ; // 类型不一样 没办法比 直接给结果
    //        
    //        // 强转
    //        Person p = (Person)o;
    //        
    //        // 此次比较完全按照 age 比较
    //        int result = this.age - p.age;
    //        System.out.println("Person.compareTo("+result+")");
    //        return result;
    //    }
        
        
    //    @Override
    //    public int compareTo(Object o) {
    //        if( !(o instanceof Person) )
    //            return 0 ; // 类型不一样 没办法比 直接给结果
    //        
    //        // 强转
    //        Person p = (Person)o;
    //        
    //        // 此次比较完全按照 sex 比较
    //        // 先规定 true = 0  false = 1 ;
    //        int result = (this.sex ? 0 : 1)  - (p.sex ?  0 : 1);
    //        System.out.println("Person.compareTo("+result+")");
    //        return result;
    //    }
        
        
    //    @Override
    //    public int compareTo(Object o) {
    //        if( !(o instanceof Person) )
    //            return 0 ; // 类型不一样 没办法比 直接给结果
    //        
    //        // 强转
    //        Person p = (Person)o;
    //        
    //        // 此次比较按照 age sex 比较    规定 true = 0  false = 1 
    //        // 先按照age比较 , age 相等 按照 sex 比
    //        
    //        int result = this.age - p.age ;
    //        if( result == 0 ) // 相等
    //            return (this.sex ? 0 : 1)  - (p.sex ?  0 : 1); // age 相等 return sex 的结果
    //        
    //        return result;// age 不等 , 直接 return age 的比较结果
    //    }
        
        
        @Override
        public int compareTo(Object o) {
            if( !(o instanceof Person) )
                return 0 ; // 类型不一样 没办法比 直接给结果
            
            // 强转
            Person p = (Person)o;
            
            // 此次比较按照 age sex  name比较    规定 true = 0  false = 1 
            // 先按照age比较 , age 相等 按照 sex 比  , sex 相等按照 name
            
            int result = this.age - p.age ;// age 的结果
            if( result == 0 ){ // 相等
                result = (this.sex ? 0 : 1)  - (p.sex ?  0 : 1); // sex 的结果
                if(result ==  0)
                    return this.name.compareTo(p.name);
            }
            return result;
        }
    }
    
    
    
    
    
    import java.util.Arrays;
    
    public class Test {
        public static void main(String[] args) {
            Person p = new Person("张三a",18, true);
            Person p2 = new Person("张三c",18, true);
            Person p3 = new Person("张三2",20, true);
            Person p4 = new Person("张三3",18, false);
            Person p5 = new Person("张三b",18, true);
            
            Person[] ps = {p , p2 , p3 , p4 , p5};
            
            // 直接把 Person 数组给Arrays 排序
            Arrays.sort(ps);
            // java.lang.ClassCastException: com.equals.Person cannot be cast to java.lang.Comparable
            
            System.out.println("=============================");
            for (Person person : ps) {
                System.out.println(person);
            }
        }
    }

      

  • 相关阅读:
    BestCoder6 1002 Goffi and Squary Partition(hdu 4982) 解题报告
    codeforces 31C Schedule 解题报告
    codeforces 462C Appleman and Toastman 解题报告
    codeforces 460C. Present 解题报告
    BestCoder3 1002 BestCoder Sequence(hdu 4908) 解题报告
    BestCoder3 1001 Task schedule(hdu 4907) 解题报告
    poj 1195 Mobile phones 解题报告
    二维树状数组 探索进行中
    codeforces 460B Little Dima and Equation 解题报告
    通过Sql语句控制SQLite数据库增删改查
  • 原文地址:https://www.cnblogs.com/symkmk123/p/9688641.html
Copyright © 2011-2022 走看看