第四章 面向对象(下)

 

第四讲

面向对象(下)

类的继承

     通过继承可以简化类的定义

     Java只支持单继承,不允许多重继承。

     可以有多层继承,即一个类可以继承某一个类的子类,如类B继承了类A,类C又可以继承类B,那么类C也间接继承了类A

     子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法。在子类的构造方法中可使用语句super(参数列表)调用父类的构造方法。

     如果子类的构造方法中没有显式地调用父类的构造方法,也没有使用this关键字调用重载的其它构造方法,则在产生子类的实例对象时,系统默认调用父类无参数的构造方法。

  

class Person

{

       private String name="unknown";

       private int age=0;

       public Person()

       {

       }

       public Person(String name,int age)

       {

              this.name=name;

              this.age=age;

       }

       void getInfo()

       {

              System.out.println("姓名:"+name+"\n"+"年龄:"+age);

       }

}

 

class Student extends Person

{

       String school="unknown";

       public Student()

       {

              //super();

              super("张三",18);

       }

}

 

class TestStudent

{

       public static void main(String[]args)

       {

              Student st=new Student();

              st.school="小学";

              System.out.println("学校:"+st.school);

              st.getInfo();

              st.school="中学";

              System.out.println("学校:"+st.school);

              new Person("李四",20).getInfo();

       }

}

运行结果:

学校:小学

姓名:张三

年龄:18

学校:中学

姓名:李四

年龄:20

子类对象的实例化过程

     分配成员变量的存储空间并进行默认的初始化,就是用new关键字产生对象后,对类中的成员变量按第三章的表3.1中的对应关系对对象中的成员变量进行初始化赋值。

     绑定构造方法参数,就是new Person(实际参数列表)中所传递进的参数赋值给构造方法中的形式参数变量。

     如有this()调用,则调用相应的重载构造方法(被调用的重载构造方法双从步骤2开始执行这些流程),被调用的重载构造方法的执行流程结束后,回到当前构造方法,当前构造方法直跳转到步骤6执行。

     显式或隐式追溯调用父类的构造方法(一直到Object类为止,Object是所有Java类的最顶层父类,在本章后面部分有详细讲解),父类的构造方法双从步骤2开始对父类执行这些流程,父类的构造方法的执行流程结束后,回到当前构造方法,当前构造方法继续往下执行。

     进行实例变量的显式初始化操作,也就是执行在定义成员变量时就对其进行赋值的语句。、

     执行当前构造方法的方法体中的程序代码

class Person

{

       public String name="unknown";

       public int age=0;

       public Person()

       {

       }

       public Person(String name,int age)

       {

              this.name=name;

              this.age=age;

       }

       void getInfo()

       {

              System.out.println("姓名:"+name+"\n"+"年龄:"+age);

       }

}

 

class Student extends Person

{

       String school="unknown";

       public Student()

       {

              //super();

              super("张三",18);

       }

       public Student(String name,int age)

       {

              super(name,age);

       }

       public Student(String name,int age,String school)

       {

              //super(name,age);

              this(name,age);

              this.school=school;

       }

       public void getInfo()

       {

              System.out.println("姓名:"+name+" 年龄:"+age+" 学校:"+school);

       }

}

 

class TestStudent

{

       public static void main(String[]args)

       {

              new Student().getInfo();

              Student st=new Student("李四",16);

              st.getInfo();

              new Student("王二麻子",21,"清华").getInfo();

       }

}

运行结果:

姓名:张三 年龄:18 学校:unknown

姓名:李四 年龄:16 学校:unknown

姓名:王二麻子 年龄:21 学校:清华

 

注意看下面代码的粗体部分及运行结果:

class Person

{

       public String name="unknown";

       public int age=0;

       public Person()

       {

       }

       public Person(String name,int age)

       {

              this.name=name;

              this.age=age;

       }

       void getInfo()

       {

              System.out.println("姓名:"+name+"\n"+"年龄:"+age);

       }

}

 

class Student extends Person

{

       String school="unknown";

       public Student()

       {

              //super();

              super("张三",18);

       }

       /*public Student(String name,int age)

       {

              super(name,age);

       }*/

       public Student(String name,int age,String school)

       {

              super(name,age);

              //this(name,age);

              this.school=school;

       }

       public void getInfo()

       {

              System.out.println("姓名:"+name+" 年龄:"+age+" 学校:"+school);

       }

}

 

class TestStudent

{

       public static void main(String[]args)

       {

              new Student().getInfo();

              Student st=new Student("李四",16);

              st.getInfo();

              new Student("王二麻子",21,"清华").getInfo();

       }

}

 

姓名:张三 年龄:18 学校:unknown

姓名:unknown 年龄:学校:unknown

姓名:王二麻子 年龄:21 学校:清华

                                                   

注意:super()this()调用语句不能同时在一个构造函数中出现。super()this()调用语句只能作为构造函数中的第一句出现。

 

覆盖父类的方法

     覆盖方法必须和被覆盖的方法具有相同的方法名称,参数列表和返回值类型。

     如果在子类中想调用父类中的那个被覆盖的方法,我们可以用super.方法的格式。

     覆盖方法时,不能使用比父类中被覆盖的方法更严格的访问权限。

class Person

{                                                                                                                                                       

              public String name="unknown";                                                                         

              public int age=-1;         

              public Person()

              {

              }

              public Person(String name,int age)

              {

                     this.name=name;

                     this.age=age;

              }                                                                                                      

              public void getInfo()                                                                                  

              {

                     System.out.println("name="+name+",age="+age);

              }                                                                                                                                                                                                                                                                                            

}                                                            

 

class Student extend Person

{

              public String school="unknown";

              public Student()

              {

                     //super();

                     super("wangwu",18);

              }

              public Student(String name,int age)

              {

                     super(name,age);

              }

              public Student(String name,int age,String school)

              {

                     //super(name,age);

                     this(name,age);

                     this.school=school;

              }

              public void getInfo()

              {

                     System.out.print(/*"name="+name+",age="+age+*/"school="+school);

                     super.getInfo();//调用父类的成员方法

              }

              public void study()

              {

                    

              }

}                  

 

class TestStudent

{

              public static void main(String[]args)

              {

                     Student st=new Student("zhangsan",18,"大学");

                     /*st.name="zhangsan";

                     st.age=20;*/

                     st.getInfo();

                    

             

              }

}

Final关键字

     Java中声明类、属性和方法时,可使用关键字final来修饰。

     final标记的类不能被继承。

     final标记的方法不能被子类重写。

     final标记的变量(成员变量或局部变量)即成为常量,只能赋值一次。

     方法中定义的内置类只能访问该方法内的final类型的局部变量,用final定义的局部变量相当于是一个常量,它的生命周期超出方法运行的生命周期,将一个形参定义成final也是可以的,这就限定了我们在方法中修改形式参数的值。

     public static final共同标记常量时,这个常量就成了全局的常量。

抽象类

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

     抽象类必须用abstract关键字来修饰;抽象方法也必须用abstract来修饰。

     抽象类不能被实例化,也就是不能用new关键字去产生对象。

     抽象方法只需声明,而不需实现。

     含有抽象方法的类必须被声明为抽象类,抽象类的子类必须覆盖所有的抽象方法后才能被实例化,否则这个子类还是个抽象类。

接口(interface)

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

     接口中的成员都是public访问类型的,接口里的变量默认是用public static final标识的。

     我们可以定义一个新的接口用extends关键字去继承一个已有的接口

     我们也可以定义一个类用implements关键字去实现一个接口中的所有方法,我们还可以定义一个抽象类用implements关键字去实现一个接口中定义的部分方法。

     一个类可以继承一个父类的同时,实现一个或多个接口,extends关键字必须位于implements关键字的之前。

 

interface Runner

{

       /*public static final*/ int ID=05;

       void run();

}

 

interface Animal extends Runner

{

       public void breathe();//必须为public类型,以下如同

}

 

abstract class LandAnimal implements Animal

{

       public void breathe()

       {

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

       }

}

 

class Fish implements Animal

{

              public void run()

              {

                     System.out.println("The fish jogs the way is the swimming");

              }

              public void breathe()

              {

                     System.out.println("The fish breath way is the bubbling");

              }

}

 

class TestAnimal

{

       public static void main(String[]args)

       {

              Fish f=new Fish();

              f.run();

              f.breathe();

              int j=0;

              //f.ID=2;无法为最终变量 ID 指定值

              System.out.println(f.ID);

              System.out.println(Fish.ID);

              //LandAnimal la=new LandAnimal(); LandAnimal 是抽象的;无法对其进行实例化

       }

}

 
对象的类型转换

     子类对象可以自动转换成父类

     父类转换成子类必须使用强制转换

     instanceof操作符可以用来判断一个实例对象是否属于一个类。

class A

{

              public void func1()

              {

                     System.out.println("A fun1 is calling");

              }

              public void func2()

              {

                     func1();

              }

}

 

class B extends A

{

              public void func1()

              {    

                            System.out.println("B func1 is calling");

              }

              public void func3()

              {

                            System.out.println("B func3 is calling");

              }

             

}

 

class C

{

              public static void main(String[]args)

              {

                            B b=new B();

                            callA(b);

                            A a=b;

                            callA(new A());

              }

              public static void callA(A a)

              {

                            if(a instanceof B)//如果aB类的一个实例对象

                                          {

                                                        B b=(B)a;

                                                        b.func1();

                                                        b.func2();

                                                        b.func3();

                                          }

                            else

                                          {

                                                        a.func1();

                                                        a.func2();

                                          }

              }

}

     Object类及equals方法

class Student

{

              String name;

              int age;

              public Student(String name,int age)

                            {

                                          this.name=name;

                                          this.age=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;

                            }

              public static void main(String[]args)

                            {

                                          Student stud1=new Student("zhangsan",20);

                                          Student stud2=new Student("zhangsan",18);

                                          if(stud1.equals(stud2))

                                                        System.out.println("equals");

                                          else

                                                        System.out.println("not equals");

                            }

}

接口实例:

interface PCI

{

              void start();

              void stop();

}

class SoundCard implements PCI

{

              public void start()

              {    

                            System.out.println("hollo");

              }

              public void stop()

              {

                            System.out.println("ByeBye");

              }

}

 

class NetWork implements PCI

{

              public void start()

              {    

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

              }

              public void stop()

              {

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

              }

}

 

class MainBoard

{

              public void usePCICard(PCI p)

              {

                            p.start();

                            p.stop();

              }

}

 

class Assembler

{

              public static void main(String[]args)

              {

                            MainBoard mb=new MainBoard();

                            NetWork nw=new NetWork();

                            SoundCard sc=new SoundCard();

                            mb.usePCICard(nw);

                            mb.usePCICard(sc);

              }

             

}

匿名内置类

interface PCI

{

              void start();

              void stop();

}

 

class SoundCard implements PCI

{

              public void start()

              {    

                            System.out.println("hollo");

              }

              public void stop()

              {

                            System.out.println("ByeBye");

              }

}

 

class NetWork implements PCI

{

              public void start()

              {    

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

              }

              public void stop()

              {

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

              }

}

 

class MainBoard

{

              public void usePCICard(PCI p)

              {

                            p.start();

                            p.stop();

              }

}

 

 

class Assembler

{

              public static void main(String[]args)

              {

                            MainBoard mb=new MainBoard();

                            NetWork nw=new NetWork();

                            SoundCard sc=new SoundCard();

                            mb.usePCICard(nw);

                            mb.usePCICard(sc);

                             mb.usePCICard(new PCI()

                             {

                                          public void start()

                                          {     

                                                        System.out.println("test start");

                                          }

                                          public void stop()

                                          {

                                                        System.out.println("test stop");

                                          }

                             });

              }

}

异常

     异常定义了程序中遇到的非致命的错误,而不是编译时的语法错误,如程序要打开一个不存在的文件、网络连接中断、操作数越界、装载一个不存在的类等。

     try,catch语句

     throws关键字

     自定义异常与throw关键字

     如何对多个异常作出处理

     我们可以在一个方法中使用throw,try…catch语句业实现程序的跳转

     一个方法被覆盖时,覆盖它的方法必须扔出相同的异常或异常的子类。

     如果父类扔出多个异常,那么重写(覆盖)方法必须扔出那些异常的一个子集,也就是说不能扔出新的异常

class Test

{

              public int devide(int x,int y) throws DevideByMinusException,ArithmeticException

              {

                            if(y<0)

                                          throw new DevideByMinusException("devide is "+y);

                            return x/y;

              }

              //以下是实现程序的跳转功能。

              /*void fun()

              {

                            try

                            {

                                          if(x==0)

                                                        throw new XxxException("xxx");

                                          else

                                                        throw new YxxException("yyy");

                                          ......

                            }

                            catch(XxxException e)

                            {

                            }

                            catch(YyyException e)

                            {

                                          ......

                            }

              }*/

}

 

class DevideByMinusException extends Exception

{

              public DevideByMinusException(String msg)

              {

                            super(msg);

              }

}

class TestException

{

              public static void main(String[]args)

              {

                            Test tt=new Test();

                            try

                            {

                                          tt.devide(4,0);

                            }

                            catch(ArithmeticException e)

                            {

                           

                                          System.out.println("Program is running into Arithmetic");

                                          e.printStackTrace();

                            }

                            catch(DevideByMinusException e)

                            {

                                          System.out.println("Program is running into DevideByMinusException");

                                          e.printStackTrace();

                            }

                            catch(Exception e)

                            {

                                          System.out.println(e.getMessage());

                            }

                            finally

                            {

                                          System.out.println("finally");

                            }

                            System.out.println("The program is running here.");

              }

}

访问控制



类本身也有访问控制,即在定义类的
class关键字前加上访问控制符,但类本身只有两种访问控制,即public和默认,父类不能是privateprotected,否则子类无法继承。Public修饰的类能被所有的类访问,默认修饰(即class关键字前没有访问控制符)的类,只能被同一包中的所有类访问。

posted on 2007-06-07 23:35 大头剑客 阅读(364) 评论(0)  编辑  收藏 所属分类: 学习笔记


只有注册用户登录后才能发表评论。


网站导航:
 
<2025年3月>
2324252627281
2345678
9101112131415
16171819202122
23242526272829
303112345

导航

统计

公告

写字楼里写字间,写字间里程序员;
程序人员写程序,又拿程序换酒钱;
酒醒只在网上坐,酒醉还来网下眠;
酒醉酒醒日复日,网上网下年复年;
但愿老死电脑间,不愿鞠躬老板前;
奔驰宝马贵者趣,公交自行程序员;
别人笑我忒疯癫,我笑自己命太贱;
不见满街漂亮妹,哪个归得程序员.
不管前面是地雷阵还是万丈深渊,
我都将勇往直前,义无反顾,
鞠躬尽瘁,死而后已。
—— 朱镕基总理

常用链接

留言簿(1)

随笔档案

文章分类

文章档案

学习园地

最新随笔

搜索

积分与排名

最新评论