Java复习笔记2--匿名类和多态

匿名类

Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.

  1. private ServiceConnection connection = new ServiceConnection() {  

  2. @Override  

  3. public void onServiceDisconnected(ComponentName name) {  

  4. }  

  5. @Override  

  6. public void onServiceConnected(ComponentName name, IBinder service) {  

  7. myBinder = (MyService.MyBinder) service;  

  8. myBinder.startDownload();  

  9. }  

    注意事项

      **1、**使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。

         2、匿名内部类中是不能定义构造函数的。

         3、匿名内部类中不能存在任何的静态成员变量和静态方法。

          4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。

         5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

     我们给匿名内部类传递参数的时候,若该形参在内部类中需要被使用,那么该形参必须要为final。也就是说:当所在的方法的形参需要被内部类里面使用时,该形参必须为final。

    拷贝引用,为了避免引用值发生改变,例如被外部类的方法修改等,而导致内部类得到的值不一致,于是用final来让该引用不可改变。

    **      故如果定义了一个匿名内部类,并且希望它使用一个其外部定义的参数,那么编译器会要求该参数引用是final的。**

    匿名内部类初始化通过写代码块,不可以写自己的构造函数

Java 多态

面向对象编程有三个特征,即封装继承多态

  封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据。

  继承是为了重用父类代码,同时为实现多态性作准备。那么什么是多态呢?

  方法的重写、重载与动态连接构成多态性。Java之所以引入多态的概念,原因之一是它在类的继承问题上和C++不同,后者允许多继承,这确实给其带来的非常强大的功能,但是复杂的继承关系也给C++开发者带来了更大的麻烦,为了规避风险,Java只允许单继承,派生类与基类间有IS-A的关系(即“猫”is a “动物”)。这样做虽然保证了继承关系的简单明了,但是势必在功能上有很大的限制,所以,Java引入了多态性的概念以弥补这点的不足,此外,抽象类接口也是解决单继承规定限制的重要手段。同时,多态也是面向对象编程的精髓所在。

多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

 对于面向对象而言,多态分为编译时多态和运行时多态。其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编译之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们所说的多态性。

向上转型

我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类。我可以通过

  Cat c = new Cat();

  实例化一个Cat的对象,这个不难理解。但当我这样定义时:

  Animal a = new Cat();

  这代表什么意思呢?

  很简单,它表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象。由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的。那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特,

  +定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。

  +所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;

  +同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;

  +对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。

对于多态,可以总结它为:

  一、使用父类类型的引用指向子类的对象;

  二、该引用只能调用父类中定义的方法和变量;

  三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)

  四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。

参数是父类,传入的是子类也属于向上转型

 

向下转型

  1. class Fruit  

  2. {  

  3. public void myName()  

  4. {  

  5. System.out.println("我是父类  水果...");  

  6. }  

  7. }  

  8. class Apple extends Fruit  

  9. {   

  10. @Override  

  11. public void myName()   

  12. {   

  13. System.out.println("我是子类  苹果...");  

  14. }  

  15. public void myMore()  

  16. {  

  17. System.out.println("我是你的小呀小苹果~~");  

  18. }  

  19. }  

  20. public class Sys{   

  21. public static void main(String[] args) {   

  22. Fruit a=new Apple(); //向上转型  

  23. a.myName();  

  24. Apple aa=(Apple)a; //向下转型,编译和运行皆不会出错(正确的)  

  25. aa.myName();//向下转型时调用的是子类的  

  26. aa.myMore();;  

  27. Fruit f=new Fruit();  

  28. Apple aaa=(Apple)f; //-不安全的---向下转型,编译无错但会运行会出错  

  29. aaa.myName();  

  30. aaa.myMore();   

  31. }  

  32. }  

a指向子类的对象,所以子类的实例aa也可以指向a啊~~

向下转型后因为都是指向子类对象,所以调用的当然全是子类的方法~~

f是父类对象,子类的实例aaa肯定不能指向父类f啊~~~

3.Java为了解决不安全的向下转型问题,引入泛型的概念

4.为了安全的类型转换,最好先用 if(A instanceof  B) 判断一下下~~

 

2种实现形式

  • 继承

    基于继承的实现机制主要表现在父类和继承该父类的一个或多个子类对某些方法的重写,多个子类对同一方法的重写可以表现出不同的行为。

  • 接口

    接口是通过实现接口并覆盖接口中同一方法的几不同的类体现的。

    在接口的多态中,指向接口的引用必须是指定这实现了该接口的一个类的实例程序,在运行时,根据对象引用的实际类型来执行对应的方法。

    继承都是单继承,只能为一组相关的类提供一致的服务接口。但是接口可以是多继承多实现,它能够利用一组相关或者不相关的接口进行组合与扩充,能够对外提供一致的服务接口。所以它相对于继承来说有更好的灵活性。

  •  

 

posted @ 2016-09-06 21:12  zhouQing  阅读(390)  评论(0编辑  收藏  举报