• Java学习笔记16---抽象类与接口的浅显理解


    抽象类是由abstract修饰的类,定义方式如public abstract class A{...}。

    接口由interface修饰,定义方式如public interface B{...}。

    抽象类与接口的具体特性见下文。

    抽象类:

    (1).抽象类中由abstract修饰的方法称为抽象方法,抽象方法没有具体实现,要等子类继承后再实现;声明方式如public abstract void run();。

    (2).只要某类中有一个方法为抽象方法,该类就必须要定义为抽象类。

    (3).抽象类不一定有抽象方法,也不一定没有非抽象方法,或者说抽象类可以没有抽象方法,也可以有非抽象方法;也就是说,一个类是不是抽象类,不是由类中是否有抽象方法决定的,而是在定义类时就确定了的,只要是由abstract修饰的类就是抽象类。对于抽象类中不含抽象方法这一点,如果不希望实例化某个类时,可以如此。

    (4).非抽象的子类继承抽象类后,必须实现父类的所有抽象方法;由于子类继承了父类的所有方法,所以,如果还有未实现的抽象方法的话,该子类就应该定义为抽象类了。继承抽象类时使用关键字extends。

    (5).抽象的子类继承抽象类后,可以不实现父类的抽象方法,也可以定义自己的抽象方法。

    (6).抽象类有构造方法,可以有成员变量,但不能实例化;需要通过继承它的子类来间接实例化。抽象类之所以叫抽象类,正是因为它比较抽象,不能具体化成某个对象,也就是说实例化的时候根本不知道要把它实例化成一个什么东西,所以它没法实例化;比如,有一个抽象类叫“生物”,实例化的时候这个“生物”长什么样呢,大家都不知道,而当“狗”这个子类继承“生物”后,再实例化狗,就知道应该怎么实例化了,狗是一个具象的概念,大体的轮廓大家都知道,至于再具体一点,哈皮狗啊吉娃娃啊,这又属于“狗”的子类了。

    接口:

    (1).接口中的所有方法都是抽象方法。

    (2).接口内的变量都是public static final的,而且必须是这样的,即使没有显式声明;也就是说,接口内的变量是静态的、不能修改的;定义时要赋初值,通过接口名来访问。一般不在接口中定义变量,我理解的是,接口可以由各种各样的类来实现,这些类可以是完全不相干的类,如果在接口中定义了变量的话,这些变量就是由实现接口的所有类共享的,实际上这些类不一定有这么些共同的属性存在,所以最好不在接口中定义变量,有需要就在各个类中各自定义比较好。

    (3).接口要由类来实现,所有方法都要实现;类只能继承一个父类,但可以实现多个接口,接口之间用逗号分隔,如 class A implements interface1,interface2。我们可以把类想像成一块软软的面团,把接口当成各种各样的豆子,花生豆是一种接口,红豆是一种接口,绿豆也是一种接口;当类要实现接口时就把豆子嵌到面团上,面团上可以按上好多种类的豆子,也即类可以实现多个接口。

    (4).接口没有构造方法,不能实例化;从这也可以理解为什么接口中的变量要是static、final的。可以把接口当成一种标准,一种固定的东西,不轻易改变,像上面的各种豆子一样,有类需要实现接口就按上一种豆子,而这些豆子不需要自己生成新的豆子,只有面团上要嵌入豆子时才拿来用,也就是说不需要生成一个接口对象,只有类需要它的时候才去实现它。

    抽象类与接口都是为了继承与多态,它们都需要子类来继承才有意义,最终目的是为了多态;子类重写了父类的方法,再通过向上转型,由父类对象引用指向子类对象,达到运行时动态调用子类方法的目的。

    抽象类是某一类事物的一种抽象,而接口不是类,它只定义了某些行为;如,“生物”类虽然抽象,但有“狗”类的雏形,接口中的run方法可以由狗类实现,也可以由汽车实现。

    如有错误,欢迎指正。

    另:如需转载,请在标题注明(转载),并在正文加上本文链接:http://www.cnblogs.com/chanchan/p/7888324.html

    其他的话:

    最近在不同的地方有两次都是偶然间发现有其他人奉行“拿来主义”,在其自己的平台上发表本人的学习笔记。我并没有标榜自己写得有多好或怎样,但看到这样的情况心里不免有点不舒服。毕竟这是我认认真真、辛辛苦苦一个字一个字码出来的,而且是牺牲自己的睡眠时间挤时间写出来的,因为每天要等娃睡了我才有点时间干点自己的事情。大家都不容易,还希望每个人都能尊重别人的劳动成果吧。

    具体例子如下:

    包animals中定义了Animal类、Mammal类、Dog类,其中Animal、Mammal都是抽象类,Mammal类继承了Animal类,Dog类继承了Mammal类;

    还定义了两个接口,Interface1和Interface2,Dog类分别实现了这两个接口。

    结果就不一一分析了。

    附代码:

    package animals;
    
    public abstract class Animal {
    
        public Animal() {
            System.out.println("Animal constructor");
        }
        
        public abstract void eat();
        public abstract void sleep();
    }
    
    
    package animals;
    
    public abstract class Mammal extends Animal {
    
        int mam = 3;
        
        public Mammal() {
            System.out.println("Mammal constructor");
        }
    
        public abstract void run(int a);
        public abstract void run();
        
        public void breathe() {
            System.out.println("Mammal:breathe");
        }
    }
    
    
    package animals;
    
    public interface Interface1 {
        int infc1 = 2;
        public abstract void run();
    }
    
    
    package animals;
    
    public interface Interface2 {
        public abstract void swim();
    }
    
    
    package animals;
    
    public class Dog extends Mammal implements Interface1,Interface2 {
    
        public Dog() {
            System.out.println("Dog constructor");
        }
        
        //animal
        public void eat() {
            System.out.println("eat");
        }
        
        //animal
        public void sleep() {
            System.out.println("sleep");
        }
        
        //mammal
        public void run(int a) {
            System.out.println("a=" + a);
            System.out.println("run(a)");
        }
    
        //interface1
        public void run() {
            System.out.println("run");
        }
        
        //interface2
        public void swim() {
            System.out.println("swim");
        }
    
        public static void main(String[] args) {
            Dog dogT = new Dog();
            Mammal mal = dogT;//向上转型
            Animal ani = dogT;//向上转型
            Interface1 infc1 = dogT;//向上转型
            Interface2 infc2 = dogT;//向上转型
            
            System.out.println(dogT.mam);
            System.out.println(dogT.infc1);
            System.out.println(Dog.infc1);
            
            System.out.println("dogT.eat():");
            dogT.eat();
            System.out.println("dogT.sleep():");
            dogT.sleep();
            System.out.println("dogT.run(8):");
            dogT.run(8);
            System.out.println("dogT.run():");
            dogT.run();
            System.out.println("dogT.swim():");
            dogT.swim();
            
            System.out.println("mal.eat():");
            mal.eat();
            System.out.println("mal.sleep():");
            mal.sleep();
            System.out.println("mal.run(9):");
            mal.run(9);
            System.out.println("mal.run():");
            mal.run();
            
            System.out.println("ani.eat():");
            ani.eat();
            System.out.println("ani.sleep():");
            ani.sleep();
            
            System.out.println("infc1.run():");
            infc1.run();
            System.out.println("infc2.swim():");
            infc2.swim();
        }
    }

    输出结果如下:

     1 Animal constructor
     2 Mammal constructor
     3 Dog constructor
     4 3
     5 2
     6 2
     7 dogT.eat():
     8 eat
     9 dogT.sleep():
    10 sleep
    11 dogT.run(8):
    12 a=8
    13 run(a)
    14 dogT.run():
    15 run
    16 dogT.swim():
    17 swim
    18 mal.eat():
    19 eat
    20 mal.sleep():
    21 sleep
    22 mal.run(9):
    23 a=9
    24 run(a)
    25 mal.run():
    26 run
    27 ani.eat():
    28 eat
    29 ani.sleep():
    30 sleep
    31 infc1.run():
    32 run
    33 infc2.swim():
    34 swim
  • 相关阅读:
    jmeter响应结果乱码问题
    JMeter 脚本请求错误 HTTP Status 415 的解决
    使用fiddler进行genymotion安卓虚拟机手机抓包
    Android模拟器Genymotion安装使用教程详解
    java基础-数组
    Qt类继承图
    Linux-磁盘管理小结
    User and User Groups in Linux
    Qt5.3编译错误——call of overloaded ‘max(int int)’is ambiguous
    i++ and ++i efficiency
  • 原文地址:https://www.cnblogs.com/chanchan/p/7888324.html
Copyright © 2020-2023  润新知