run_wind

导航

黑马程序员--第一阶段3.面向对象--第9天

-------------------- android培训java培训、期待与您交流!--------------------

 

 

抽象类

java中可以定义一些不含方法体的方法,它的方法体的实现交给该类的子类根据自己的情况去实现,这样的方法就是抽象方法,包含抽象方法的类就叫抽象类。

  • 抽象类必须用abstract关键字来修饰;抽象方法也必须用abstract来修饰。
  • 抽象类不能被实例化,也就是不能用new关键字去产生对象。
  • 抽象方法只需声明,而不需实现。
  • 含有抽象方法的类必须被声明为抽象类,抽象类的子类必须覆盖所有的抽象方法后才能被实例化,否则这个子类还是个抽象类,而且必须用abstract修饰类名

接口(interface)

如果一个抽象类中的所有方法都是抽象的,我们就可以将这个类用另外一种方式来定义,也就是接口定义。接口是抽象方法和常量值的定义的集合,从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。

  1. 接口中的成员都是public访问类型的。接口里的变量默认是用public static final标识的。
  2. 我们可以定义一个新的接口用extends关键字去继承一个已有的接口
  3. 我们也可以定义一个类用implements关键字去实现一个接口中的所有方法,我们还可以去定义一个抽象类用implements关键字去实现一个接口中定义的部分方法。
  4. 一个类可以继承一个父类的同时,实现一个或多个接口,extends关键字必须位于implemnets关键字之前。

示例如下:

1.         interface Animal extends Runner  //一个接口继承另一个接口
{
    int ID=1; // 因为默认为public static final,相当于常量,所以变量名大写
    void breathe();
}
interface Runner
{
    void run();
}

2.         class Fish implements Animal  //一个类实现一个接口的所有方法
{
    public void run()
    {
       System.out.println("鱼的游泳代码");
    }
    public void breathe()
    {
       System.out.println("鱼的呼吸代码");
    }
    public static void main()
    {
         Fish f=new Fish();
         int y=0;
         y=Runner.ID;    //因为是static 所以可以直接引用
         y=Fish.ID;      //从Fish从Runner继承来的
         y=f.ID;
         f.ID=5;         //错误,因为ID 是final型的
    }
}

3.         abstract class LandAnimal implements Animal  //一个抽象类实现接口中的
{                                                    //部分方法
    public void breathe()
    {
       System.out.println("陆生生物呼吸的代码");
    }
}

4.         class Student extends Person implements Animal  //一个类继承一个父类,
{                                                        //并且实现一个接口的
    public void run()                                 //所有方法
    {
       System.out.println("学生奔跑的代码");
    }
    public void breathe()
    {
       System.out.println("学生呼吸的代码");
    }
}
class Person
{
    String name="unknown";
}

5.         class Bird implements Runner,Flyer   //一个类实例多个接口的所有方法
{
    public void run(){}
    public void fly(){}
}
interface Flyer
{
    void fly();
}

定义接口类用“interface 类名”的方式,如:

interface A

{

       String name=”戴振良”;  //接口中的成员变量系统会默认加上“public static final”修饰符

       int func1(int x);  //接口类中的方法不需要用abstract修饰

       void func2();

}

 

 

//接口的应用,该程序模拟主板插声卡与插网卡的应用

 

interface  PCI          //定义PCI接口的规范

{

    void start();

    void stop();

}

class soundCard implements PCI     //按照PCI接口的规范定义声卡的功能

{

    public void start()

    {

       System.out.println("嘟嘟嘟...");

    }

    public void stop()

    {

       System.out.println("停止声音");

    }

}

class networkCard implements PCI       //按照PCI接口的规范定义网卡的功能

{

    public void start()

    {

       System.out.println("发送数据信息....");

    }

    public void stop()

    {

       System.out.println("停止发送数据");

    }

}

class mainbord           //按照PCI接口的规范定义主板PCI卡槽的功能

{

    public void usePCICard(PCI pci)

    {

       pci.start();

       pci.stop();

    }

}

class assembler      //定义一个电脑组装者

{

    public static void main(String[] args)

    {

       mainbord mb=new mainbord();     //组装者买了一块主板

       soundCard sc=new soundCard();      //组装者买了一块声卡

       networkCard nc=new networkCard();      //组装者买了一块网卡

       mb.usePCICard(sc);       //把声卡插到主板上,拥有了声音的功能

       mb.usePCICard(nc);       //把网卡插到主板上,拥有了发送数据的功能

       mb.usePCICard(new PCI()     //匿名内置类的使用非常之多,要熟练掌握。这里定义了

              {                   //了一个匿名内置类,相当于厂商制作了一个PCI规范的卡,用于测试主板

                     public void start()

                     {

                         System.out.println("测试主板……");

                     }

                     public void stop()

                     {

                         System.out.println("停止测试");

                     }

              }

       );

    }

}

 

//上面的匿名内置类相当于:

/*class A implements PCI

{

    public void start()

    {

       System.out.println("Test Start");

    }

    public void stop()

    {

       System.out.println("Test Stop");

    }

}

mb.usePCICard(new A());  */

 

 

对象的类型转换

  • 子类对象可以自动转换成父类                                                                                                   
  • 父类转换成子类必须使用强制转换。
  • instanceof 操作符可以用它来判断一个实例对象是否属于一个类。Object类及equals方法
    假如B继承于A:
    A a=new B( );//这是可以的,但使用a实例时只能使用A类中有的方法或B类的重写方法
    B b=(B) a;//必须这样做才能把实例a赋值给子类b
    if(a instanceof B)//判断实例a是否是B类的类型的实例
  • 如果在声明一个类时没有写明继承哪一个类的话,则默认继承了Object类,如声明“class a”等“class a extends Object”
  • object类中有一个equals方法,用于比较两个对象是否相等,即比较两个对象中的属性值是否都相等。  注意在使用时必须重写该方法,否则就会一直都是返回false,重写代码如下:
        假设有个Student类,类中有一个name成员与age成员:
        public boolean equals (Object obj)
        {
            Student st=null;
            if(obj instanceof Student)
            {
                 st=(Student)obj;
                 if(st.name==name&&st.age=age)
                      return true;
                 else
                      return false;
             }
             else
                 return false;
        }
  • equals的用法:st1.equals(st2);

 

面向对象的多态性

  1. 应用程序不必为每一个派生类(子类)编写功能调用,只需要对抽象基类进行处理即可。这一招叫“以不变应万变”,可以大大提高程序的可复用性。
  2. 派生类的功能可以被基类的引用变量引用,这叫向后兼容,可以提高程序的可扩充性和可维护性。以前写的程序可以被后来程序调用不足为奇,现在写的程序(如callA方法)能调用以后写的程序(以后编写的一个类A的子类,如类D)就了不起了。

匿名内部类

abstract class A

{

       abstract public void fun1();

}

class Outer

{

public static void main(String [] args)

{

new Outer().callInner(new A()

{

                     public void fun1()

                     {

                            System.out.println("implement for fun1");

                     }

});

}

public void callInner(A a)

{

              a.fun1();

}

}

//匿名内置类的使用非常多,要熟练掌握

 

 

-------------------- android培训java培训、期待与您交流!--------------------

 

 

posted on 2012-04-25 10:29  run_wind  阅读(119)  评论(0编辑  收藏  举报