Java(2):Java SE疯狂复习第2篇(多态)

来源:互联网 发布:如何建立的电影数据库 编辑:程序博客网 时间:2024/05/16 16:13

0. 引言


一鼓作气,再而衰,三而竭。要考研了,好好复习。(为什么别人考研,我这么紧张?)

Review:Java SE疯狂复习第1篇

据说,多态虽然用得不多(估计是低端码农们用得不多了,要设计什么大型兼容通用的框架的话,还是用一用有利于团队合作和开发),

但是,它在OOP程序员应聘的时候,却占有核心地位。

所以,本文就花了很大的篇幅和笔墨,来总结多态现象。

同样的,因为借鉴了太多别人的东西,所以文章类型就选为”转载“了。


1. 多态


OOP的核心,多态(polymorphism )。

1. 多态性:访问子类可以通过访问父类:(不是很能理解他在说什么)【尽快查证】

Animal cat =new Cat();

Animal dog =new Dog();

2. 在使用多态的时候,如果有使用覆盖函数,那么被覆盖的方法(即是父类中的的那个相应的方法)是要存在的。

3.  多态:一个引用(类型)在不同情况下的多种状态,可使代码更加灵活

4. java允许父类的引用变量引用它子类的实例,是自动完成的


这里先放上一个经典案例。

运行结果是这样的。

我不到吃什么 // Animal父类的方法eat; 父类很抽象(共性),并不知道有什么特性。多态是由其子类的特性体现出来的(late binding, dynamic binding)。
不知道怎么叫 // 父类的方法cry;
狗喜欢吃骨头 // Dog继承了父类Animal,并根据狗这个class的特性,override了父类的方法eat;
骨头 // Bone继承了父类Food,并根据骨头这个class的特性,override了父类的方法;
猫喜欢吃鱼 // Cat继承了父类Animal,并根据猫这个class的特性,override了父类的方法eat;

注意。居然可以这样写。父类 变量名 = new 子类。(如果C++要实现多态的话,恐怕要用ref或pointer,再加virtual function了)

在上面,标红的文字,都是对”多态性“的描述。


2. 抽象类


1. 父类方法的不确定性,用抽象类修饰这个方法,abstract。

2. 抽象类还是可以一样被继承

3. 当一个类继承的类是抽象的类时候,就要把抽象类中的所有的抽象方法全部方法实现

4. 用abstract关键词来修饰的时候,一定是抽象类和抽象方法

5. 在使用中不多,公司笔试的时候考很多

6. 抽象类不能被实例化,只有被继承以后再去实例化

7. 抽象类不一定要包含abstract方法,但就算没有abstract方法,也不能实例化它

8. 一旦类包含了abstract方法,这个类必须声明为abstract

9. 抽象方法不能有主体“{ }”

看起来,和第1大点里,Animal那个例子很类似。

注意区别!

abstract class Animal{    String name;    int age;    abstract public void cry();   }
//当一个类继承的类是抽象的类时候,就要把抽象类中的所有的抽象方法全部方法实现class Cat extends Animal{    public void cry()    {       //do nothing       System.out.println("喵喵叫");          }}

3. 接口与抽象接口


java不允许多继承。如果想要实现多继承的效果,可以去实现多个接口。
接口已经是抽象的了(已经不能被实例化了),那抽象接口是什么?(暂时还没有体会)
有点像C++里的虚函数和纯虚函数(虚基类)。【有待对比】

据某人的笔记,
10. 接口就是给出一些没有内容的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。
举个例子。

Person接口。

/** *  */package com.qcy.inter;/** * @author qcy * */public interface PersonInter {void speaking();}
Student类。

/** *  */package com.qcy.test;import com.qcy.inter.PersonInter;/** * @author qcy * */public class Student implements PersonInter{@Overridepublic void speaking() {// TODO Auto-generated method stubSystem.out.println("student speaking");}}
Teacher类。

/** *  */package com.qcy.test;import com.qcy.inter.PersonInter;/** * @author qcy * */public class Teacher implements PersonInter {@Overridepublic void speaking() {// TODO Auto-generated method stubSystem.out.println("teacher speaking");}}

和第1大点中,Animal能实例化不一样。

上面,Animal是一个class,是可以实例化的。作为父类,它的派生类(子类)可以去override它的成员方法,也可以不override。

这里,只要是接口,就不能被实例化。如果某些class要去implement这个接口,必须去override在接口里声明过的方法。此时,多态表现为不同的class也许有不同的实现方式。

再举一个更诡异的例子!

package com.qcy.test;public class Inter_demo_1 {    public static void main(String[] args)    {       Computer computer=new Computer();       Camera camera=new Camera();       Phone phone=new Phone();       computer.useUsb(camera);       computer.useUsb(phone);    } } interface  Usb{    //声明了两个方法    //开始工作    public void start();    //停止工作    public void stop();   } //照相机,实现Usb接口//一个类实现接口就要把所有的方法全部实现!class Camera implements Usb{    public void start()    {       System.out.println("我是照相机,我开始工作了!");    }    public void stop()    {       System.out.println("我是照相机,我停止工作了!");          }      } //手机类 class Phone implements Usb{    public void start()    {       System.out.println("我是手机,我开始工作了!");      }    public void stop()    {       System.out.println("我是手机,我停止工作了!");            }   } //计算机class Computer{      //开始使用USB接口    public void useUsb(Usb usb)//体现多态    {       usb.start();       usb.stop();       }}

运行结果。

我是照相机,我开始工作了!
我是照相机,我停止工作了!
我是手机,我开始工作了!
我是手机,我停止工作了!

这种写法很诡异!!但是也不是不能理解。

注意useUsb(Usb usb)这个函数。形式参数是个接口!但实际参数却是一个实现了这个接口的类!

语法规定,就这么写了。多态是OOP的一个现象,大概也可以理解为语法现象了……

这也是体现多态性的一个例子。

要这样写,或者这样做,估计也只会在什么大型、超大型的工程里去用了。

比如,要写一个什么通用的框架(e.g. spring)。

大概,是一种”规范性“,”通用性“,”代码写作的一致性“和”兼容性“的体现吧。——qcy的感想。因为这好像不是必须的啊,因为要实现这个功能,完全也可以不这样写嘛。只是说有这个东西,好像开发起来配合起来写作起来,更愉快,更高效,更统一。

11.接口不能被实例化

12.接口中的所有方法都不能有主体

13.抽象类里面是可以有实现了的方法的

14.接口中的所有方法都不能有主体,即都不能被实现

15.接口是更加抽象的抽象类!!!!

16.一个类继承抽象类或是使用接口,那么就要实现所有的抽象方法

17.一个类可以实现多个接口

18.接口中可以有变量(但是不能用private,protected修饰)

19.接口中的变量本质上都是静态的,而且是final,不管你加不加static,所以可以直接使用:接口名.变量名

20.在 java开发中,经常把常用的变量定义在接口中作为全局变量使用

  访问形式:接口名.变量名

21.一个接口不能继承其它的类,但是可以继承别的接口

22.接口体现了程序设计的多态和高内聚低耦合的思想


其他琐碎的感想


1. 实现接口和继承父类的区别:

java是单继承,一个类只允许继承一个父类,这种单继承的机制可以保证类的纯洁性,比C++的多继承机制简洁

实现接口可以看做是对单继承的一种补充

继承是层次式的,不太灵活,修改某个类就会打破这种继承的平衡,但是接口就不会,因为只针对实现接口的类才起作用


2. 前期绑定:在程序运行之前就进行绑定,由编译器和连接程序实现,又叫静态绑定,如static方法和final方法,包括private方法,它是隐式fi nal的

3. 后期绑定:在运行的时候根据对象的类型进行绑定,由方法调用机制实现,因此又叫动态绑定,或是运行时绑定,除前期绑定外的所有方法都属于后期绑定


4. final概念:final可以修饰变量和方法

当不希望父类的某些方法被子类覆盖的时,可以用final修饰

当不希望类的某个变量的值被修改,可以用final修饰(有点像C++里的const)

当不希望类被继承时,可以用final修饰


5. final修饰的变量一般用下划线书写

如果一个变量是final的,那么定义时候必须赋初值

6. final修饰的变量又叫常量,一般用XX_XX_XX命名

7. final什么时候用:

出于安全的考虑,类的某个方法不允许修改

类不会被其它的类继承

某些变量值是固定不变的,比如PI。
0 0
原创粉丝点击