Java编程技术课件:06类的高级特征(4学时)_第1页
Java编程技术课件:06类的高级特征(4学时)_第2页
Java编程技术课件:06类的高级特征(4学时)_第3页
Java编程技术课件:06类的高级特征(4学时)_第4页
Java编程技术课件:06类的高级特征(4学时)_第5页
已阅读5页,还剩60页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Java编程技术6 类的高级特征6.1 static关键字6.2 final关键字6.3 抽象类abstract6.4 接口interface6.5 内部类Java编程技术6.1 static关键字n 通常情况下,类成员必须通过类的对象来访问,但是可以创建这样的成员,它的使用完全独立于该类的任何对象。n static关键字用来声明成员属于类,而不是属于类的实例。n 如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。Java编程技术static用法n 静态方法n 静态变量n 静态块代码【Return】Java编程技术静态方法class Simple

2、void go() test t=new test(); t.go2(); / 不推荐用对象.静态方法 static void go1() System.out.println(Go1.); / 静态方法public class test static void go2() System.out.println(Go2.); / 静态方法 void go3() System.out.println(Go3.); public static void main(String args) / 静态方法 new Simple().go(); /OK go2(); /OK go3(); / NO Si

3、mple.go1(); /OK 静态方法调用:类名.静态方法(参数) 静态方法有以下几条限制: 它仅能调用其他的static 方法。 它只能访问static数据。 它不能以任何方式引用this 或super【Return】静态方法只能调用静态方法Why?Java编程技术补充:static方法不能调用非static方法和变量 why?n 对于一般的非static成员变量和方法,需要有一个对象的实例才能调用,所以要先生成对象的实例,它们才会分配内存空间。n static方法在程序装载class时候首先完成,比构造方法早,此时非static的属性和方法还没有完成初始化。所以static方法不能调用非

4、static方法和属性。Java编程技术静态变量public class Wrong int x; static int y; / 静态变量 public static void main(String args) x = 9; / NO this.y=10 ; / NO, 直接用y=10 或者 Wrong.y=10; 静态方法只能访问静态数据静态方法不能以任何方式引用this 或superWhy?Java编程技术补充:static方法不能引用this 或super why?n this是当前对象的引用。也就是说this只能用它来调用属于当前对象的方法和属性。n static方法如果使用的是类

5、来调用而不是对象,则 this将无法指向合适的对象。Java编程技术注意一下 n 声明为static的变量实质上就是全局变量。所有此类的实例(对象)都共享此静态变量。n 在类装载时,静态变量只分配一块存储空间,所有此类的对象都可以操控此块存储空间。 n 对于final型static变量(全局不可修改的变量)则另当别论。 Java编程技术示例class Value static int c=0; static void inc() c+; class Count public static void prt(String s) System.out.println(s); public stat

6、ic void main(String args) Value v1=new Value(); Value v2=new Value(); prt(v1.c=+v1.c+ v2.c=+v2.c); Value.inc(); /也可 v1.inc();但不推荐 prt(v1.c=+v1.c+ v2.c=+v2.c); 结果如下:v1.c=0 v2.c=0v1.c=1 v2.c=1通过类的实例访问静态变量Java编程技术补充一点n 如果static变量没有被标记成private,也可以不需要类的实例,而通过类名指向它。即“类名.静态变量”。 public class StaticVar publi

7、c static byte SOURCE_SP=0; public static byte SOURCE_TABLE=1; public static byte SOURCE_JAVABEAN=2;public class OtherClass public void method(byte sourceType) if(sourceType = StaticVar.SOURCE_SP) 前提【Return】Java编程技术静态块代码 静态代码块: static 语句块 n 静态块代码只会初始化一次,且在类被第一次装载时。n 类中不同的静态块按它们在类中出现的顺序被执行。Java编程技术示例c

8、lass StaticInitDemo static int i = 5; static System.out.println(Static code i=+ i+ ); public class Test public static void main(String args) System.out.println(Main code: i= + StaticInitDemo.i ); 运行结果:Static code: i=5Main code: i=6Java编程技术阅读程序class Value static int c=0; Value() c=15; Value(int i) c=

9、i; static void inc() c+; public class Count public static void prt(String s) System.out.println(s); Value v=new Value(10); / static Value v1,v2; / static / prt(v1.c=+v1.c+ v2.c=+v2.c); v1=new Value(27); prt(v1.c=+v1.c+ v2.c=+v2.c); v2=new Value(15); prt(v1.c=+v1.c+ v2.c=+v2.c); public static void ma

10、in(String args) Count ct=new Count(); / prt(ct.c=+ct.v.c); / prt(v1.c=+v1.c+ v2.c=+v2.c); v1.inc(); prt(v1.c=+v1.c+ v2.c=+v2.c); prt(ct.c=+ct.v.c); 运行结果:v1.c=0 v2.c=0v1.c=27 v2.c=27v1.c=15 v2.c=15ct.c=10v1.c=10 v2.c=10v1.c=11 v2.c=11ct.c=11Java编程技术分析n static定义的变量会优先于任何其它非static变量,不论其出现的顺序如何。(因此虽然v出现

11、在v1和v2的前面,但是结果却是v1和v2的初始化在v的前面。)n 静态代码块通常用来进行显式的静态变量初始化,静态代码块只会初始化一次,且在类被第一次装载时。类中不同的静态块按它们在类中出现的顺序被执行。n 在涉及到继承的时候,会先初始化父类的static变量,然后是子类的,依次类推。n 因此可以得到程序运行的主要顺序如所示。 【Return】Java编程技术6.2 final关键字n final类n final方法n final变量n final参数【Return】Java编程技术final类n 在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么

12、就设计为final类。因此final类的成员方法没有机会被覆盖。n 如Java.lang.String类就是一个final类。【Return】Java编程技术final方法n final方法可以被继承,但不能被覆盖。n 使用final方法的原因有二:n 把方法锁定,防止任何继承类修改它的意义和实现。n 高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。Java编程技术示例public class Test1 public void f1() System.out.println(f1); public final void f2() System.out.println

13、(f2); public static void f3() System.out.println(f3); private void f4() System.out.println(f4); public class Test2 extends Test1 public void f1() System.out.println(父类f1被覆盖!); public void f2() / NO System.out.println(父类f2被覆盖!); public void f3() / NO System.out.println(父类f3被覆盖!); public void f4() Sys

14、tem.out.println(f4); 无法被子类覆盖的方法实际上被标记为static或private的方法被自动final。【Return】无法覆盖静态方法继承Java编程技术final变量 n 如果变量被标记为final,其结果是使它成为常数。改变final变量的值会导致编译错误。 n 例如:final double PI = 3.14159;n 注意:final变量定义的时候,可先声明,不给初值,(称为final空白变量)。但空白final在使用之前必须被初始化。 n final修饰的变量有三种:静态变量、实例变量和局部变量。 Java编程技术示例public class Test3

15、private final int A=100; public final int B=90; public static final int C=80; private static final int D=70; public final int E; public Test3(int x) E=x; private void test1() System.out.println(new Test3(1).A); /OK System.out.println(Test3.B); /NO非静态 System.out.println(Test3.D); /OK System.out.print

16、ln(Test3.E); /出错没赋值 public void test2() final int a; /需要时才赋值 final int b=4; /局部常量 final int c; /一直没赋值. a=3; /a=4; b=2; 出错,已赋值 public static void main(String args) Test3 t=new Test3(2); /要初始化E /t.C=33; /出错 System.out.println(t.A); /OK 100 System.out.println(t.B); /ok 90 System.out.println(t.C); /不推荐使

17、用 80 System.out.println(Test3.C); /ok 80 /System.out.println(Test3.E); /出错,未初始化 System.out.println(t.E); /ok,已经初始化E 2 final变量可先声明,而不给初值,但须在初始化对象的时候赋初值【Return】Java编程技术final参数 n 当函数参数为final类型时,只可以读取使用该参数,但是无法改变该参数的值。 public class Test4 public static void main(String args) f1(2); public static void f1(

18、 final int i ) /i+; 出错,final类型值不允许改变 System.out.print(i); 【Return】Java编程技术6.3 抽象类n Java类中可以定义一些不含方法体的方法,它的方法体的实现将交给该类的子类根据自己的情况去实现,这样的方法就是抽象方法,包含抽象方法的类就叫抽象类。 abstract class A /抽象类 private int i=1; abstract int aa(int x,int y); abstract void bb(); public void cc() System.out.println(i); class B exten

19、ds A int aa(int x,int y) return x+y; void bb() /空操作也算实现 public static void main(String args) B b=new B(); System.out.println(b.aa(1,2); b.cc(); 实现抽象方法抽象类抽象类提供一个类型的部分实现实现抽象方法含有抽象方法的类必须被声明为抽象类继承抽象类Java编程技术抽象类特点n 含有抽象方法的类必须被声明为抽象类。抽象类中不一定包含的都是抽象方法。n abstract方法只需声明,而不需实现。n 抽象类可以有构造方法,但构造方法不能被声明为抽象。n 抽象类

20、提供一个类型的部分实现,所以不能被实例化,即不能用new去产生对象,但可声明对象。 n 抽象类的子类必须覆盖所有的抽象方法后才能被实例化,否则这个子类还是个抽象类。 n 抽象类不能用final来修饰,即一个类不能既是最终类又是抽象类。n abstract不能与private、static、final并列修饰同一个方法。因为不能被继承或覆盖Java编程技术抽象类编程示例 n 定义一个抽象类Animal:n公有属性:animalNamen构造函数:Animal(String)n抽象方法:eat() n 定义抽象类Animal的两个子类:Horse和Dog类n各自都有构造函数:Horse(Strin

21、g)、Dog(String)n各自实现父类的抽象方法:eat(),输出:马吃草料!狗吃骨头!Java编程技术抽象类 - Animalpublic abstract class Animal public String animalName; Animal(String s) /抽象类可以有构造函数,但不能声明为抽象 animalName=s; public abstract void eat(); /抽象方法Java编程技术Horse类和Dog类public class Horse extends Animal Horse(String s) super(s); /调用父类的构造方法 publ

22、ic void eat() /实现抽象方法 System.out.println(animalName+吃草料!); public class Dog extends Animal Dog(String s) super(s); /调用父类的构造方法 public void eat() /实现抽象方法 System.out.println(animalName+吃骨头!); Java编程技术测试类public class test public static void main(String args) Animal h = new Horse(马); Animal d = new Dog(狗

23、); h.eat(); d.eat(); 多态体现不能用:Animal a=new Animal() 抽象类不能被实例化Java编程技术抽象类编程练习n 定义一个抽象类Person:n 私有属性:namen 构造函数:Person(String)n 普通方法:getName()n 抽象方法:getIntro()n 定义Person类的两个子类:n Employee类:含有私有属性 GongZin Student类:含有私有属性 ZhuanYen 各自实现父类抽象方法getIntro()输出:张三, 职工张三的月工资为:6000.0李四, 学生李四的专业是:计算机应用Java编程技术代码参考-抽

24、象类abstract class Person private String name; public Person(String aName) name=aName; public abstract String getIntro(); /抽象方法 public String getName() return name; Java编程技术参考代码 - Employee和Student类 class Employee extends Person private double GongZi; public Employee(String aName,double aGongZi) super(

25、aName); GongZi=aGongZi; public String getIntro() /重写抽象方法 return 职工+ getName() +的月工资为:+GongZi; class Student extends Person private String ZhuanYe; public Student(String aName,String aZhuanYe) super(aName); ZhuanYe=aZhuanYe; public String getIntro() /重写抽象方法 return 学生+ getName() +的专业是:+ZhuanYe; Java编程

26、技术测试代码public class test public static void main(String args) Person person=new Person2; /对象数组 person0=new Employee(张三,6000); /多态体现 person1=new Student(李四,计算机应用); for( Person e : person ) System.out.println(e.getName()+, +e.getIntro(); 抽象类不能被实例化,但可声明对象。【Return】Java编程技术此例作为“接口编程”前导练习n 定义一个几何图形Shape抽象类

27、,声明两个抽象方法:ndouble circum(); 求周长ndouble area(); 求面积n 定义Shape类的两个子类:n矩形类Rectangle:私有数据长length和宽widthn圆形类Circle:私有数据半径 rn两个类均要实现求周长和求面积功能。 Java编程技术6.4 接口interfacen 接口是一种特殊的抽象类:n 如果一个抽象类中的所有方法都是抽象的,这个类就定义为interface接口。n 接口的所有方法通常由子类全部实现,不同子类的实现可以具有不同的功能。 Java编程技术接口编程示例n 定义一个几何图形Shape接口,该接口声明两个方法:ndouble

28、circum(); 求周长ndouble area(); 求面积n 定义Shape类的两个子类:n矩形类Rectangle:私有数据长length和宽widthn圆形类Circle:私有数据半径 rn两个类均要实现求周长和求面积功能。 从本例中要体会:接口提供的是一种统一的“协议”Java编程技术接口定义interface Shape double area(); double circum();说明:(1) 接口内方法默认都是公有、抽象的,即public abstract可以省略(2) 接口内不能有属性变量,接口没有构造函数(区别于抽象类)接口关键字Java编程技术Rectangle类实现接

29、口class Rectangle implements Shape private double height; private double width; public Rectangle(double height,double width) this.height = height; this.width = width; public double area() return height * width; public double circum() return 2 * (height + width); 实现接口的类必须实现接口规定的所有方法实现接口的关键字Java编程技术Cir

30、cle类实现接口class Circle implements Shape private double radius; public Circle(double radius) this.radius = radius; public double area() return Math.PI * radius * radius; public double circum() return 2 * Math.PI * radius; 实现接口的类必须实现接口规定的所有方法Java编程技术测试代码public class test public static void main(String a

31、rgs) Shape r=new Rectangle(10,10); Shape c=new Circle(10); System.out.println(矩形面积=+ r.area(); System.out.println(圆面积=+ c.area(); System.out.println(矩形周长=+ r.circum(); System.out.println(圆周长=+ c.circum(); 多态体现Java编程技术接口编程练习n 将上节“马吃草料,狗吃骨头”的抽象类例子改为用接口编程实现。注意:接口不能有构造函数,不能被实例化。而抽象类可以有构造函数,但也不能实例化。Java编

32、程技术多接口n Java只支持单继承,不支持多继承。n 但一个类可以实现多个接口,从而间接的实现多继承。Java编程技术多接口实现框架interface Shape1 double area(); interface Shape2double circum(); class Rectangle implements Shape1,Shape2 public double area() /实现方法(不同的类可能有不同的实现) public double circum() /实现方法 实现类要实现所有接口的所有方法接口关键字接口的方法没有实现都是public abstract(可省略)类可实现多个

33、接口间接实现多继承Java编程技术多接口编程interface Shape1 public double area();interface Shape2 public double circum();Rectangle类Circle类n 编写求解几何图形(包括矩形、圆形等)的周长、面积的程序,要求使用多接口实现。 Java编程技术Rectangle类实现多接口class Rectangle implements Shape1,Shape2 private double height; private double width; public Rectangle(double height,do

34、uble width) this.height = height; this.width = width; public double area() return height * width; public double circum() return 2 * (height + width); 类必须实现接口所有方法主要代码没有任何改变Java编程技术Circle类实现多接口class Circle implements Shape1,Shape2 private double radius; public Circle(double radius) this.radius = radiu

35、s; public double area() return Math.PI * radius * radius; public double circum() return 2 * Math.PI * radius; 类必须实现接口所有方法主要代码没有任何改变Java编程技术Java接口的特点 n Java接口不能有构造函数(构造器),不能被实例化。n Java接口中的成员常量(不能有变量)默认是 (可省略),都是全局静态常量,必须被显示初始化。n Java接口中的方法默认都是类型的(可省略),没有方法体。 n 接口中不能包含静态方法。区别:抽象类可以有构造函数public interfac

36、e A int var; /错,var不是变量,实际是public static final常量必须初始化 public A().; /错,接口中不能包含构造函数 void method() .; /错,接口中只能包含抽象方法,没有方法体 protected void method2(); /错,接口中的方法必须是public类型 static void method3(); /错,接口中不能包含静态方法Why?Why?Why?Java编程技术思考:接口中不允许定义变量 why?n 接口提供的是一种统一的“协议”,接口中的属性也属于“协议”中的成员。n 如果接口可以定义变量,由于接口中的方法都

37、是抽象的,这样在接口中无法通过行为来修改属性。n 如果通过实现接口的对象的行为来修改接口中的属性,那么实现该接口的所有对象也都会自动拥有这一改变后的值(因为 static 的静态共享),这就和接口提供的统一的抽象这种思想相抵触。Java编程技术Java接口的特点(续)n 当一个类实现某个接口时,它必须定义这个接口的所有抽象方法(包括这个接口的父接口中的方法),否则这个类必须声明为抽象的。n 一个接口不能实现(implements)另一个接口。n 但一个接口可继承(extends)多个其它的接口。 interface b interface c interface a implements b

38、/错,接口不能实现接口 interface a extends b,c /对,接口可以多继承接口 可以定义一个抽象类去实现一个接口中定义的部分方法。Java编程技术示例public interface A void methodA();public interface B void methodB();public interface C extends A, B /接口可继承多个其它的接口 void methodC();public interface C implements A /错,接口不能实现另一个接口. public class E implements C / 类可实现多个接口/

39、必须实现接口所有的方法,如methodA(), methodB(), methodC()A a = new A(); /错误,接口不允许实例化A a = new E(); /可以。接口类型变量可引用实现该接口的实例Java编程技术Java接口的特点(完)n 一个类在继承一个父类的同时,可实现一个或多个接口,但extends关键字必须位于implements关键字之前。n 例如:public class A extends B implements C, D .n 不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例。(多态)【Return】Jav

40、a编程技术接口编程练习定义一个整形堆栈IntStack接口,包含2个方法:void push(int item) 和 int pop()(1)创建一个FixedStack类,实现一个固定长度的整数堆栈。interface IntStack void push(int item); int pop(); public class testStack public static void main(String args) FixedStack mystack1=new FixedStack(5); for(int i=0;i5;i+) mystack1.push(i); System.out.p

41、rint(Stack in mystack1:); for(int i=0;i5;i+) System.out.print(mystack1.pop()+ ); Java编程技术public class FixedStack implements IntStack private int stck ;private int pos;public FixedStack(int size) stck=new intsize; pos=-1; public int pop() if(pos0) System.out.print(Stack is underflow.); return -1; /不是

42、特别好 else return stckpos-; public void push(int item) if(pos=stck.length-1) System.out.print(Stack is full.); else stck+pos=item; FixedStackJava编程技术接口编程(续)(2)创建一个动态栈DynStack类,每个栈都以一个初始长度构造,如果初始化长度被超出,则堆栈的大小将成倍增加(原有数据要保留)。 public class testStack public static void main(String args) DynStack mystack1=n

43、ew DynStack(5); for(int i=0;i10;i+) mystack1.push(i); System.out.print(Stack in mystack1:); for(int i=0;i10;i+) System.out.print(mystack1.pop()+ ); Java编程技术public class DynStack implements IntStack private int stck;private int pos;public DynStack(int size) stck=new intsize; pos=-1; public int pop()

44、if(pos0) System.out.print(Stack is underflow.); return -1; else return stckpos-; public void push(int item) if(pos=stck.length-1) int temp =new intstck.length*2; for(int i=0;istck.length;i+) tempi=stcki; /转存 stck=temp; stck+pos=item; else stck+pos=item; DynStackJava编程技术接口总结n 接口仅仅描述系统能做什么,但不指明如何去做,所有

45、接口中的方法都是抽象方法。n 接口不涉及和任何具体实例相关的细节,因此接口没有构造方法,不能被实例化,没有实例变量。n 接口是构建松耦合软件系统的重要法宝。【Return】Java编程技术接口思考n 什么时候使用接口? n 接口与抽象类的区别?n 为什么 Java 接口中不允许定义变量 ?Java编程技术6.5 内部类n 内部类,有时叫做嵌套类。n 内部类允许一个类定义被放到另一个类定义里。n 内部类是一个有用的特征,因为它们允许将逻辑上同属性的类组合到一起,并在另一个类中控制一个类的可视性。 Java编程技术示例public class Parcel class Destination /内

46、部类 private String label; Destination(String whereTo) label = whereTo; String readLabel() return label; public void ship(String dest) Destination d = new Destination(dest); System.out.println(d.readLabel(); public static void main(String args) Parcel p = new Parcel(); p.ship(New York); 在类的方法中使用内部类与使用

47、普通类没多大区别内部类构造函数Java编程技术示例如何在类的成员方法创建内部类实例public class Outer1 private int size; public class Inner /声明一个内部类 public void doStuff( ) size+; /内部类可以访问外部内成员 public void testTheInneer( ) Inner i= new Inner( ); /类的成员方法创建内部类实例 i.doStuff( ); Java编程技术示例如何在其它类创建内部类实例public class Outer2 private int size;public class Inner /内部类 public void doStuff( ) size+; public class TestInneer /其他类 public static void main(String args) Outer2 outer

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论