黑马程序员————多态、抽象类、接口简述



 ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------



一、多态

一多态:某一事物在某一时刻表现出来的多种形态。父类的引用指向了他的某个子类的对象。


1、多态的前提
    1).一定要有继承关系的
    2).有方法重写
    3).父类引用指向了子类的对象

2、多态成员的访问特点:--》》父类应用不能访问子类特有的成员(变量、方法)
     1).普通的成员变量
        A):只能访问父类中定义成员变量;若是父类没有定义时,则就是编译错误。。(无覆盖)
        B):若发生覆盖时,父类引用指向了子类的对象,访问的是父类的成员变量。
  编译看左边:编译时父类必须有此成员,否则报错
  执行看左边:执行时,打印的结果看左边的引用类型。
 
 2).普通的成员方法
     A:未发生重写时,访问父类的方法。
     B:发生重写,访问子类的方法。
  编译看左边:编译时,父类需要有此方法,否则编译错误。
  运行看右边:运行时,看引用的指向对象,运行的是子类中的方法。
  
 方法空间
  A:多个对象时,每个对象都有独立的成员变量空间。但“方法空间”只有一个,多个对象共享一个“方法空间”。
  B:多个对象调用“同一方法“时,会使用动态绑定。哪一个对象调用方法,其调用的属性就是实例化对象的类中的属性。而调用方法的引用是一个地址值,是所调用的方法所在类实例化对象的堆内存地址值。
  

   3).静态的成员方法
  静态的成员都是和类有关系的,跟对象无关的,没有动态绑定的。
  编译看左边:编译时,父类要有此类方法,否则编译出错的;若是父类没有此方法,则父类不能访问。
  执行看右边:运行时,运行还是父类的方法。
  看静态方法和一般的成员方法是有区别的,所有说 静态的方法重写不能算是真正的方法重写。

 3、总结:多态时,属性和静态的方法的调用看引用,成员方法调用看对象!!!

 多态发生时,父类的引用指向子类的对象,可以理解为,基本数据类型的默认提升!!!!

二、面试题:
1、复杂的子父类调用情况


class Fu
{
   public void show()
   {
     System.out.println("fu show");
   }
}

class Zi extends Fu
{
   public void show()
   {
      System.out.println("zi show");
   }

   public void method()
   {
      System.out.println("zi method");
   }
}
class Test
{
   public static void main(String[] args)
   {
      Fu f = new Zi();
      f.method();
   }
}

 此题运行错误,是因为父类引用访问不到子类特有的方法。



2、子父类的方法调用关系


class A
{
   public void show()
   {
     show2();
   }
 
   public void show2()
   {
     System.out.println("我");
   }
}
class B extends A 
{
    public void show2()
    {
      System.out.println("爱");
    }
}
class C extends B 
{
    public void show()
    {
      super.show();
    }
 
    public void show2()
    {
      System.out.println("你");
    }
}

public class Test 
{
    public static void main(String[] args) 
    {
       A a = new B();   
       a.show(); //父类的引用指向子类对象,会首先调用父类的未被复写的方法show(),其中有show2()方法,由于show2()方法被子类重写,访问子类的方法

       B b = new C();
       b.show(); //B类型的引用指向了C子类的对象,首先调用父类B的show()方法,此时B类中”隐含着“一个show()方法,
                 //方法中有show2()方法,由于show2()方法被子类C重写,所以调用子类的show2方法。
    }
}


输出的是”爱 你“





三、多态的好处
 1、提高了程序的维护性,由继承保证---》》在方法声明上,形式参数为引用型变量的时候传递的是引用也就是内存地址值。其形参变量,可以接受任何子类类型的引用,因为多态,因为形参是父类类型的。
 2、提高了程序的扩展性,由多态保证





四、多态中的类型转换--》》用来访问子类特有的功能
 1、向上转型:父类的引用指向了子类的对象,隐式自动转换
  特点:A:多态;B:访问的是父类中定义的成员,子类特有的不可以访问。
 2、向下转型:如果确定父类引用指向了某个子类对象,那么可以将这个父类类型的引用强制转换为该子类类型的引用。必须是所对应的子类类型引用,其他的类不可以。

3、案例:

class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
以及
Animal p0 = new Animal();
Dog p1 = new Dog ();
Cat p2 = new Cat ();
Animal p3 = new Dog ();
Animal p4 = new Cat ();

p0 = p1; //可以的,理解为Animal p0=new Dog();
p1 = p2; //不可以,相互没有继承关系
p1 = (Dog)p3; //可以啊,强制类型转化
p2 = (Cat)p4; //强制类型转换



4、instanceof关键字---》》用于向下转型时 判断所用
 1)、这是一个双目运算符
 2)、格式:父类类型变量 indtanceof 某类类型;if(a instanceof B){
       System.out.println("a 指向的是 B的对象,可以安全向下转换为B类型");
       B b2 = (B)a;}
 3)、他会返回一布尔类型的值,如果是子父类关系,返回值为true
 4)、用于向下转换之前进行判断


五、抽象类
 (一)抽象类概述

1.父类中的方法被所有子类重写
 2.抽象方法,可以只有方法声明,而没有方法体,使用关键字 abstracet
 3.如果父类中有一个方法是“抽象方法”,那么该类必须也是抽象类 Abastracet class
 4.如果是抽象类,那么该类就不能被实例化了,不能有该类对象了
 5.一个抽象类,就是用来做父类的,被其他类来继承

(二)、抽象类的特点
 1.抽象类和抽象方法,用关键字abstract修饰。格式:abstract class 类名;public abstract void 方法名
 2.抽象类中和抽象方法中可以什么都不定义。但是有抽象方法必须是抽象类。
 3.抽象类中可以有什么?
  A:成员变量(包括静态)
  B:成员方法(包括静态方法)
  C:构造方法也可以有,子类在实例化对象的时候会调用父类的无参或者有参的构造方法
  D:抽象方法,可以只有方法声明,但是没有方法体。
 4.子类可以继承一个抽象类,仍旧是单继承
 5.子类继承一个抽象类,那么必须要▲全部▲重写父类的抽象方法。如果重写一部分或者重写不完全,那么子类也必须是抽象的



(三)、抽象类总结
 1.抽象类是不可以被实例化的,但是可以在多态中通过子类实例化
 2.子类继承抽象类,必须重写全部抽象方法。若不能全部重写,那么子类必须也是抽象的。
 3.一个抽象类可以继承自一个抽象类
 4.一个类中有抽象方法那么这个类也必须是抽象类,而一个抽象类中可以没有抽象方法。


(四)、抽象类中成员的特点
 1.成员变量:可以是变量也可以是常量
 2.成员方法:抽象方法和非抽象方法
  抽象方法:用于限定子类必须完成某些动作
  非抽象方法:用于提高代码的复用性
 3.构造方法:必须有构造方法,可以是无参也可以是有参数的,但是类本身不能被实例化。用来实例化子类对象时初始化父类的数据。


(五)抽象类的小问题
 1、一个抽象类中没有抽象方法,可以吗?如果可以有什么意义?
 可以的,一个抽象类可以没有抽象方法,但是一个抽象方法必须在一个抽象类中。可以用来作为一个父类来被人继承,且能防止本类被实例化。
 A:可以有成员变量和成员方法被子类继承提高代码的复用性
 B:而抽象的方法可以被重写,对子类一种约束
 
 2、abstract不能和那些关键字共存?
 A:abstract方法是抽象方法,用来被子类重写的,所以不能和private、final共存
 B:abstract的方法第一个抽星方法,是可以没有方法体的,不能分配内存空间,但是static是一个静态的方法,在没有创建对象的时候就会分配内存空间。



六、接口interface  
 (一)接口的概述
 》》如果一个抽象类中的★方法都是抽象★方法时,就可以定义为接口。★
 ★★1.当一个抽象类中没有用来实现功能的方法,只有抽象方法
 ★★2.接口和抽象类一样不可以被”实例化“,所以用来做父类
     3.子类是”实现接口“,使用关键字implantment
     4.如果一个子类实现某一个接口 ,那么必须★全部重写★接口中所有的抽象方法。否则这个类必须是抽象类。
     5.接口中可以定义什么?
      ★★A:接口可以定义成员变量》》★只能是全局常量★,声明为public static final
      ★★B:成员方法》》★只能是抽象方法★,且必须声明为public abstract,可以不用声明,但是编译器会隐式的自动添加。为什么?因为接口就是用来扩展功能的,
          C:构造方法???
 ★★6.接口中的方法都是抽象方法,可以只有方法声明,而没有方法体

(二)接口的特点
 1、使用关键字,interface;格式:interface 接口名
 2、子类实现接口,关键字 :class 类名 implements 接口名
 3、接口本身是个抽象的感念,不能实例化,可以在多态中,通过具体的子类实例化。
 4、一个子类可以实现多个接口,必须重写所有接口中的抽象方法。格式:class 类名 implements A,B,C{}
 5、一个接口可以继承自另一个接口或者多个接口,可以多继承
 6、一个抽象类可以实现接口,可以实现多个接口,而且可以不重写全部或者不全部重写接口中的方法。
 7、一个类可以同时继承自一个父类,并且实现一个或者多个接口,要先继承后实现。

(三)类、抽象类、接口的关系
 1、一个类可以继承自一个类,但必须是单继承。
 2、一个类可以继承自一个抽象类,也是单继承。
 3、一个类可以实现多个接口,多实现
 4、一个抽象类可以继承自一个抽象类,单继承,并且实现多个接口。
 5、一个接口可以继承多个接口,多继承。

(四)抽象类和接口的区别
 相同点:都不能被实例化
 区别:1、第一的关键字不同
       2、子类使用时,接口要实现,抽象类要被继承
       3、内部成员:
  接口:成员变量,加上 public static
  抽象类:成员变量
   成员方法、构造方法、抽象方法


你可能感兴趣的:(多态,对象,抽象类,接口)