1、1第六章第六章 面向对象(下)面向对象(下)2主要内容l this与与superl 构造方法的多态与继承构造方法的多态与继承l 抽象类与接口抽象类与接口l 引用引用l 类的其他相关内容类的其他相关内容36.1 this与super 6.1.1 this的用法的用法this指代指代当前对象当前对象 this()this.成员变量成员变量 this.成员方法成员方法this当参数传递给其他方法当参数传递给其他方法【例【例6.1】46.1.2 supersuper引用当前对象继承自父类的成员引用当前对象继承自父类的成员 super.数据成员数据成员 super.成员方法成员方法 super()5 c
2、lass Person int age;int height;void eat()void sleep()Person()class Student extends Person int score;Student()void study()this可引可引用的范围用的范围Person()Student score study()Student()age height eat()sleep()super可引可引用的范围用的范围6运行结果如下:运行结果如下:x=4 y=1class name:Ax=5 y=1class name:AAI am an AAz=10 x=6 super.x=5 y=
3、1 super.y=1【例【例6.2】Ax=4;y=1Void Printme()AAx=4;y=1xVoid Printme()int z=super.x+6;super.x=5super.Printme();System.out.println(I am an +this.getClass().getName();。x=4 在 子在 子类 对 象 中类 对 象 中隐藏隐藏此处调用的是父类代此处调用的是父类代码及对应的父类对象码及对应的父类对象中的属性成员中的属性成员。76.2 构造函数的多态和继承n一个类可以定义多个构造函数,构造函数之间用this()相互调用n构造函数不能被继承,可以在子
4、类构造函数中用super()调用父类构造函数【例【例6.3】【例【例6.4】86.3 抽象类抽象类6.3.1 抽象类的定义抽象类的定义用用abstract修饰的类称为抽象类,修饰的类称为抽象类,用用abstract修饰的成员修饰的成员方法方法称为抽象方法。称为抽象方法。对于抽象方法,在抽象类中只指定方法名对于抽象方法,在抽象类中只指定方法名及类型,而不写实现代码。及类型,而不写实现代码。9public abstract class 类名类名 extends 父类名列表父类名列表 /数据成员声明数据成员声明/抽象方法抽象方法声明声明 publicabstract返回值返回值 方法名方法名(参数参
5、数列表列表)throw 异常列表异常列表 【例【例6.5】10 抽象类中可以有抽象类中可以有零个零个或或多个多个抽象方法,也抽象方法,也可以包含可以包含非抽象非抽象方法。方法。只要有一个抽象方法,类前就必须有只要有一个抽象方法,类前就必须有abstract修饰。若没有抽象方法,类前也可修饰。若没有抽象方法,类前也可有有abstract修饰。修饰。11 抽象类不能创建对象,创建对象由具抽象类不能创建对象,创建对象由具体子类来实现,但可以有体子类来实现,但可以有声明声明,声明能,声明能引用所有具体子类的对象。引用所有具体子类的对象。12 抽象类必定要派生子类,若派生的子类是抽象类必定要派生子类,若
6、派生的子类是具体类,则具体子类中必须实现抽象类中定具体类,则具体子类中必须实现抽象类中定义的义的所有抽象方法所有抽象方法(覆盖);若子类还是抽(覆盖);若子类还是抽象类,父类中已有的象类,父类中已有的abstract方法,则子类方法,则子类中就不能再有。中就不能再有。13 在抽象类中,非抽象方法可以调用抽象在抽象类中,非抽象方法可以调用抽象方法。方法。abstract不能与不能与final并列修饰同一个类;并列修饰同一个类;abstract 不能与不能与private,static,final或或 native并列修饰同一个方法;并列修饰同一个方法;abstract 类类中不能有中不能有pri
7、vate成员成员 146.3.2 抽象类的产生过程抽象类形成的思维过程:客观事物抽象类形成的思维过程:客观事物对象对象类类抽象类。抽象类。如:矩形、三角形、圆形类的属性和方法如图如:矩形、三角形、圆形类的属性和方法如图 :Protected int x,y;Protected int width,height;Public double getPerimeter()Public double getArea()矩矩形形Protected int x,y;Protected double radius;Public double getPerimeter()Public double getAr
8、ea()圆圆(x,y)(x,y)widthheightrxyzwidthheight(x,y)15对以上三类进行抽象对以上三类进行抽象 :Public double getPerimeter()Public double getArea()矩矩形形Public double getPerimeter()Public double getArea()圆圆Public double getPerimeter()Public double getArea()三三角角形形图64protected int x,y,k;protected double m;abstract public double g
9、etPerimeter()abstract public double getArea()s sh ha ap pe es s166.3.3 抽象类在继承方面的应用【例【例6.6】n简化子类定义n明晰类的层次关系17 public double x,y;public double k,m;public double getPerimeter()public double getArea()T Tr ri ia an ng gl le e public double x,y;public double k,m;public double getPerimeter()public double g
10、etArea()C Ci ir rc cl le et tr ri i6.3.4 引用具体子类对象【例【例6.7】186.3.5 抽象类设计注意事项n抽取同类对象的共同行为n包含对象的本质n尽可能简单196.4 接口(接口(interface)接口的两种含义:l可以被引用调用的方法(public方法或同包中的protected方法或默认方法);l另一种是同“类”概念地位相当的专有概念interface,interface是方法说明的集合。20 interface声明格式 public interface 接口名extends 父接口名列表 /静态常量数据成员声明 publicstaticfin
11、al 域类型 域名=常量值 /抽象方法声明 publicabstract返回值 方法名(参数列表)throw 异常列表 21 定义接口要注意几点接口定义用关键字interface,而不是用class,interface前的修饰符要么为public,要么为缺省。接口具有继承性,可通过extends关键字声明接口的父接口。22 接 口 定 义 的 数 据 成 员 全 是接 口 定 义 的 数 据 成 员 全 是 f i n a l static(静态常量静态常量)。即使没有修饰符,其。即使没有修饰符,其效果也等效,访问级别要么为效果也等效,访问级别要么为public,要么为要么为缺省缺省。23 接
12、口中没有接口中没有构造构造方法;所有成员方法都是方法;所有成员方法都是抽象方法抽象方法(与抽象类有所不同)。即使没(与抽象类有所不同)。即使没有修饰符,其效果完全等效,访问级别要有修饰符,其效果完全等效,访问级别要么为么为public,要么为,要么为缺省缺省。注:方法前不。注:方法前不能修饰为能修饰为final。246.4.2 接口的角色 接口扮演将实现者和使用者有机联系到一起的角色。256.4.3 接口实现与使用给接口中的方法定义具体的操作就是接口的实现在类的声明中用implements子句来表示一个类实现了某个接口。26 接口实现要注意几点一个类可以实现多个接口,在implements后用
13、逗号隔开多个接口的名字。一个接口也可被多个类来实现。接口的实现者可以继承接口中定义的常量,其效果等效于在这个实现类当中定义了一个静态常量。27 如果实现某接口的类不是如果实现某接口的类不是abstract的抽的抽象类,则类必须实现接口的象类,则类必须实现接口的所有所有抽象方法,抽象方法,而且方法头部分应该与接口中的定义完全而且方法头部分应该与接口中的定义完全一致。一致。如果实现接口的类是如果实现接口的类是abstract类,则它类,则它可以不实现该接口的所有方法。可以不实现该接口的所有方法。28 接口的抽象方法的访问限制符只能为接口的抽象方法的访问限制符只能为缺省或缺省或public,类在实现
14、方法时,必,类在实现方法时,必须显式使用须显式使用public修饰符,否则将被修饰符,否则将被警告为缩小了接口中定义的方法的访警告为缩小了接口中定义的方法的访问控制范围。问控制范围。【例【例6.8】296.5 抽象类与接口抽象类接口共同点 二者都可具有抽象方法,都不能实例化,但都可以有自己的声明,并能引用子类或实现类对象。不同点属性变量可以有变量 不能有,只能是静态常量。成员方法 可以有具体方法(而且具体方法可以调用抽象方法)。如果有方法,则全部是抽象方法。实现策略必须有子类继承必须有实现类实现扩展性弱强306.6 引引 用用l引用如何形成:先声明,后赋予对象,引用如何形成:先声明,后赋予对象
15、,成为引用。成为引用。l抽象类声明进行引用有什么特点?抽象类声明进行引用有什么特点?抽象类引用可以指向所有具体子类对象,抽象类引用可以指向所有具体子类对象,此概念可以推广到所有具有父子关系的类,此概念可以推广到所有具有父子关系的类,以及接口和实现类以及接口和实现类31l引用可以替换吗?替换是有原则的:父类引用可以指向子类对象,子类声明不能引用平行级别的其它类的对象,也不能引用父类对象。32l父类声明和子类声明引用同一个子类对象有什么区别?父类声明是从父类的角度去引用对象,子类声明是从子类角度引用对象。父类引用子类对象时,可以经过显式的转化赋给子类的声明,但子类的引用赋值给父类的声明则不需要。3
16、3l接口声明进行引用有什么特点?接口声明进行引用有什么特点?只能引用实现类对象的接口方法。只能引用实现类对象的接口方法。346.7 类的其它相关内容 6.7.1 类的初始化构造方法声明时初始化静态块实例块 35静态块class A static./静态块静态块在类被加载到内存时被执行非静态成员变量不能在静态块中使用静态块主要用来初始化静态变量及静态方法36 class Outer static int a=10;static System.out.println(“Hi”);a=30;Outer()System.out.println(“创建对象创建对象”);public static voi
17、d main(String args)Outer outer=new Outer();System.out.println(“Hello”);System.out.println(a);37实例块class A ./实例块实例块在创建类的实例对象时被执行实例块先于构造函数执行38 class Outer int a;System.out.println(“实例块实例块”);a=30;public Outer(int a)System.out.println(“构造函数构造函数”);this.a=a;public static void main(String args)Outer outer=
18、new Outer(10)System.out.println(outer.a);39 6.7.2 内部类内部类(Inner Class)在一个类的内部嵌套定义的另一个类,在一个类的内部嵌套定义的另一个类,称为称为内部类内部类。包含内部类的类称为。包含内部类的类称为外部外部类类。40 定义内部类与普通类定义基本相同内部类如果定义在外部类成员的位置,可看作外部类的成员,能被protected或private修饰内部类定义在方法内,则不能被任何修饰符修饰41种类种类说明说明 成员类成员类作为类的成员而存在于某个类作为类的成员而存在于某个类的内部的内部静态类静态类 作为类的静态成员而存在于某作为类的
19、静态成员而存在于某个类的内部个类的内部匿名类匿名类 存在某个类内部,但无名称的存在某个类内部,但无名称的类类局部类局部类存在某个方法内部的类存在某个方法内部的类42 成员类(member class)成员类形式如下:class Outer class Inner 43Inner类可以引用Outer类的所有成员,包括被private修饰的 class Outer private int a=10;void f()class Inner int d=a;f();44Outer类与Inner类成员重名时,利用关键字this引用成员45 class Outer int a;class Inner in
20、t a=20;void f()int a=10;System.out.println(a);System.out.println(this.a);System.out.println(Outer.this.a);46成员类的成员不能为static成员,但允许静态常量存在 class Outer class Inner int a;/可以 void f()/可以 static final int b=10;/可以 static int c;/错误 static void g()./错误 47只有创建了Outer类对象之后,才能创建Inner类对象,才能使用Inner类的成员 Outer out=
21、new Outer();Outer.Inner in=out.new Inner();【例【例6.9】48静态类(static class)静态类形式如下:class Outer static class Inner 49静态类Inner只能引用Outer类的static成员,不能引用普通成员 class Outer static int a=10;void f()static class Inner int d=a;/static变量 f();/不能引用普通方法 50Inner类作为Outer类的静态成员,可以在不创建Outer类对象的条件下,直接创建Inner类对象 Outer.Inner
22、 in=new Outer.Inner();【例【例6.10】51 局部类(local class)局部类形式如下:void f()class Inner 52局部类与局部变量类似,仅在方法内部才可以创建对象,一旦方法执行完毕,就会释放内存而消亡。53局部类可以引用包含自身的类的所有成员 class Outer int a=10;void f()class Inner System.out.println(a);54局部类只能引用方法体内的常量,不能访问方法体内的局部变量 class Outer void f(final int a,int b)int c=10;final int d=40;
23、class Inner System.out.println(a);System.out.println(b);/错误 System.out.println(d);【例【例6.11】55 匿名类(anonymous class)没有类名的内部类就是匿名类。用一条语句完成匿名类的定义与实例创建。格式一:class A new 类A()/定义类且创建对象 方法体 此时产生的对象是类A的子类对象【例【例6.12】56格式二:格式二:Interface Anew 接口接口A()()方法体方法体此时产生的对象是接口此时产生的对象是接口A的实现类。的实现类。【例【例6.13】57匿名内部类的使用原则匿名内
24、部类的使用原则匿名内部类不能有构造方法匿名内部类不能有构造方法不能定义任何静态成员、方法不能定义任何静态成员、方法不能被不能被public、protected、private、static修饰修饰只能创建一个实例只能创建一个实例586.7.4 匿名对象 匿名对象就是在产生对象时没有显式地为这个对象建立引用。Person p1=new Person();p1.shout();改为new Person().shout();【例【例6.14】59匿名对象在两种情况下经常使用:匿名对象在两种情况下经常使用:如果对一个对象只需要进行一次方法调用。如果对一个对象只需要进行一次方法调用。将匿名对象作为参数传
25、递给一个函数调用。将匿名对象作为参数传递给一个函数调用。606.7.5 类对象l在java.lang包中有一个特殊的类Class(注:同关键字class区别的地方是首字母大写),它也继承Object类。61通过调用对象方法通过调用对象方法getClass而得到而得到Class对象,进而我们可以知道类的相关的一些对象,进而我们可以知道类的相关的一些特性,如:类的名称、类的包、类的方法、特性,如:类的名称、类的包、类的方法、类的父类等。类的父类等。【例【例6.15】62小结 本章深入介绍了Java面向对象的一些概念。重点内容是引用,因为Java中的封装、继承、多态、抽象类、接口等概念都和引用有关。