350 likes | 622 Views
第 8 章 继承、抽象类和接口 包、内部类. 8.4 内部类与匿名类. 内部类 (Inner Class) 是定义在 类中的类 内部类 : 将逻辑上相关的类放到一起 匿名类 (Anonymous Class): 一种特殊的内部类. 8.4.1 内部类. 内部类也称“嵌套类” , 包含内部类的类称为“外部类” 内部类看作是外部类的一个成员,所以称为“成员类”. 1 内部类的定义方法与其它类相同 2 内部类可以被声明为: private , protected 3 内部类存取外部类的 所有成员 ( 含私有 ) 。
E N D
第8章 继承、抽象类和接口 包、内部类
8.4 内部类与匿名类 内部类(Inner Class)是定义在类中的类 内部类:将逻辑上相关的类放到一起 匿名类(Anonymous Class):一种特殊的内部类
8.4.1 内部类 • 内部类也称“嵌套类” , • 包含内部类的类称为“外部类” • 内部类看作是外部类的一个成员,所以称为“成员类” • 1 内部类的定义方法与其它类相同 • 2 内部类可以被声明为:private , protected • 3 内部类存取外部类的所有成员(含私有)。 • 外部类通过内部类对象访问内部类的成员(含私有) • 4 内部类通过 外部类名.this.成员 访问外部类的同名成员 • 5 在其他类中使用内部类:外部类.内部类;建对象:外部对象.new 内部类名( )
6 非静态内部类,不能定义静态成员(类成员)。 • 静态内部类可以定义静态成员。 • 7 内部静态类中只能访问外部类的静态成员。 • 8 static 方法中不能访问非 static 成员。 也不能 new 创建非static 的内部类。
内部类访问外部类的成员 class Outer { //内部类 private int size ; public class Inner { private int x=1; public void doStuff(){ size ++; } } public void testInner(){ Inner i=new Inner(); i.doStuff(); i.x++; System.out.println( size); } } public class demo{ public static void main(String args[]){ Outer o = new Outer(); o.testInner(); } } 外部类使用内部类
o size testInner() Outer对象 i x doStuff(); Inner对象 outer.this
public void testInner(){ Inner i=new Inner(); i.doStuff(5); } public static void main( String args[]){ Outer o = new Outer(); o.testInner(); } } class Outer { //内部类 private int size ; public class Inner { private int size =3; public void doStuff(){ int size ; size ++; this.size ++; outer.this.size ++; System.out.println(size); System.out.println(this.size); System.out.println( Outer.this.size); } }
class Outer { //其他类中建立内部类对象 private int size=1 ; public class Inner { private int x; inner(int a){ x = i; } public void doStuff(){ size ++; } } public void testInner(){ Inner i = new Inner(2); i.doStuff(); System.out.println( size); } } public class Demo { public static void main(String args[]){ Outer oo = new Outer(); oo.testInner(); Outer.Inner o_i1 = oo.new Inner() ; o_i1.doStuff(); Outer.Inner o_i2 = new Outer().new Inner() ; } }
改错: class A { //内部类 private int x,y; A(){ x=0;y=0;} A(int i,int j) { x=i;y=j;} void show(){System.out.println( x+”,”+y); } public class B { private int y , z=0; B(int m){ y = m;} public void inc(){ x++; y++; A.y++;} void show(){ A.show() , System.out.print(y); } } public void f1() { B b1 = new B(2); z++; b1.inc(); b1.show(); } } public class innerClass { public static void main(String args[]){ A a1= new A(7,9); a1.f1(); a1.B.show(); } }
class A { //静态内部类 private int x=1 ; private static int y=9; void show(){System.out.println(x +”,”+y);} static void print(){System.out.println( y);} public static class B{ B(){}; void f1(){ System.out.print(y); print();} static void f2(){ System.out.print(y); } ; } void testB(){ B b1 = new B(); b1.f1(); B.f2(); } }
class A { //静态内部类 改错 private int x=1 ; private static int y=9; public static class B{ static int z=2; B(){}; void f1(){ System.out.print(x+”,”+y);} } public class C { static int k; void f2(){System.out.print(k); } } void testB(){ B b1 = new B(); b1.f1(); C c1 = new C(); c1.f2(); } static void testC(){ B b1 = new B(); b1.f1(); C c1 = new C(); c1.f2(); } }
class A { //静态内部类 改错 private int x=1 ; private static int y=9; public static class B{ void f1(){ System.out.print(y);} } void testB(){ B b1 = new B(); b1.f1(); } } public class Demo { public static void main(String args[] ){ A a1 = new A() ; A.B b2 = a1.new B(); //new A.B(); } }
public class Group { //内部类与外部类的访问规则 private int age; public class Student { String name; public Student(String n,int a) { name=n; age=a; } public void output() { System.out.println(“姓名:”+name+”,年龄:”+age); } } public void output() { Student stu=new Student(“刘 洋”,24); stu.output(); } public static void main(String args[]) { Group G=new Group(); G.output(); } }
class app8_15 {//静态内部类的访问 注意错误 public static void main(String args[]) { A.B a_b=new A().newB(); //正确 A a=new A(); A.B ab=new a.new B(); Outer.Inner oi=new Outer.Inner(); // Outer.Inner oi2=Outer.new Inner(); //错误 // Outer.Inner oi3=new Outer().new Inner(); //错误 } } class A { private int x; void m() { new B();} static void sm() { // new B() //错误! } class B { //内部类 B(){x=5;} } } class Outer { static class Inner { } }
8.4.2 匿名内部类 匿名内部类(anonymous inner class):利用内部类创建没有名称的对象,并利用它访问到类里的成员。 语法格式1: (new 父类名(){ 方法名(参数1,参数2,…,参数n) { 方法体语句; } } ).方法名(参数1,参数2,…,参数n);
语法格式2: 父类名 <对象名>= new 父类名(){ 方法名(参数1,参数2,…,参数n) { 方法体语句; } }
匿名类 • 1 在一个表达式内部建立没有类名的内部类 • 2 无法自己定义构造方法,仅有默认构造方法 • 3 匿名类一定是一个类的子类 • ( new 父类名(){ 类体 } )
class A { //匿名类演示 private int x =1; void show(){ System.out.println(x); } } class B { public static void main( String args[]){ ( new A() { public void show(){ System.out.println("bb“+x); } } ).show(); } } A的无名子类:
abstract class A { //匿名类演示 private int x =1; void show(){ System.out.println(x); } abstract f1(); } class B { public static void main( String args[]){ A a = new A() { void show(){ System.out.println("bb“+x); } void f1(){ System.out.println(“f1”); } } ; a.show(); a.f1(); } }
class A { //匿名类 private int x ; void show(){ System.out.println(x);} } class B { static void fun( A a1){ a1.show(); } public static void main( String args[]){ fun( new A() { public void show(){ System.out.println("aa");} } ) ; } }
class A { //匿名类 改错 private int x ; A(int i) { x = i; } void show(){ System.out.println(x); } } class B { public static void main( String args[]){ A a = new A() { A(int k ){ super(k) ; } void show(){ System.out.println("bb“+x); } void f1(){ System.out.println(“f1”); } } ; a.show(); a.f1(); } }
8.5 包 • 包(package):管理类名空间。 • 文件夹把各种文件组织在一起 • 包把各种类组织在一起,使得程序功能清楚、结构分明。 8.5.1 包的概念 包:区别类名空间的机制,是类的组织方式。 包:对应一个文件夹,包中还可以再有包,称为包等级。
8.5.2 使用 package 语句创建包 package 包名1[.包名2[.包名3]…]; (1)无package语句,则为无名包 (2)有名包的创建: package dir1 package dir1.dir2 dir是一个文件夹,存放.class文件,包中的“.”号表示子文件夹。 (3) 有名包中类的存储位置 package dir1.dir2 存储在 classpath指定文件文件夹下的dir1.dir2
8.5.3 Java中的常用包 Java的常用包有:
8.5.4 利用import语句引用Java定义的包 如果要使用Java包中的类,在源程序中用import语句导入所需要的类。 import <包名1>[.<包名2>[.<包名3>…] ].<类名>|* 如: import dir1.dir2.Myclass import dir1.* 注意:* 仅代表本包中的所有类,不代表子包中的类
三 设置CLASSPATH环境变量 1 CLASSPATH变量指明“.class”文件存放的位置。 2 编译时:javac –dCLASSPATH路径Myclass.java 例如:javac –d d:\javalib myclass.java 则直接在d:\javalib下创建在myclass.java指明的包目录,并把Myclass.class拷到该目录下。 如:javac -d d:\javalib testA.java • 自动创建 mytool 文件夹, • testA.class 存在 d:\javalib\mytool • testA.java 在 d:\javalib
包设计 1 classpath 设置为:d:\javalib 2 testA.class 存储于 d:\javalib\mytool 3 packageDemo.class 存储于 d:\javalib 4 java packageDemo package mytool; //testA.java public class testA{ public void show(){ System.out.println(“hello”); } } import mytool.testA; public class packageDemo{ public static void main(String args[]){ testA a1=new testA(); a1.show(); } } 存储: d:\javalib packageDemo.class mytool testA.class
package mytool; //testA.java public class testA{ public void show(){ System.out.println(“hello”); } } public class packageDemo{ public static void main(String args[]){ mytool.testA a1=new mytool.testA(); a1.show(); } }
package pk1; //改错 A.java class A{ int x=2; protected int y=5; void show(){ System.out.println(x+y); } } package pk2; //B.java class B extends A { int z=9; void show(){ System.out.println(x+y+z); } } public class packageDemo2{ //packageDemo2.java public static void main(String args[]){ A a1=new A(); a1.show(); B b1= new B(); b1.show(); } }
package pk1; public class A{ protected int x=2; protected int y=5; public void show(){ System.out.println(x+y); } } package pk2; import pk1.A; public class B extends A { int z=9; public void show(){ System.out.println(x+y+z); } } import pk1.*; import pk2.*; public class packageDemo2{ public static void main(String args[]){ A a1=new A(); a1.show(); B b1= new B(); b1.show(); } }
1 在 Dos 下编译并运行成功。 2javac 命令中 –d 参数的作用? 3 在 eclipse 中运行 练习包的制作 1)testA 类存储在 testA.java 中 package mytool; public class testA{ public void show(){ System.out.println(“TestA: hello ”); } } 2) testB 类存储在 testB.java 中 package mytool.tool; import mytool.testA; public class testB{ public void show(){ System.out.println(“TestB: hello ”); } } 3) testC 类存储在 testC.java 中 import mytool.testA; import mytool.tool.testB; public class testC{ public static void main(String args[]){ testB b1=new testB(); b1.show(); } }
包练习: 1)文件名 packageDemo.java 中有类:, public class packageDemo{ public static void main(String args[]){ A a1=new A(); a1.show(); B b1 = new B(); b1.show(); C c1 = new C();c1.show(); D d1 = new D();d1.show(); } 2) 文件 A.java 存储在包 pk_A 中,有类: class A { private int x=3; void show(){ System.out.println(“A”+x) ;} } 3) 文件 B.java 存储在包 pk_B 中,有类: class B { void show(){ System.out.println(“B”) ;} } 3) 文件 C.java 存储在包 pk_C 中,有类: class A1 extends A { void show(){ System.out.println(“C” + x) ;} } 4)文件 D.java 存储在包 pk_B.pk_B1 中,有类: class D { void show(){ System.out.println(“D”) ;} } 请完善上述程序,改正可能的错误,并调试运行。腿脚
package pk1; //A.java 改错 public class A{ public int x=2; protected int y=5; public void show(){ System.out.println(x+y); } } package pk2; //B.java import pk1.*; public class B extends A { int z=9; public void show(){System.out.println(x+y+z); } } import pk1.*; //Demo.java import pk2.*; public class Demo{ public static void main(String args[]){ A a1=new A(); a1.show(); B b1= new B(); b1.show(); } }
Java程序组成结构如下 • 1 package: 0或1个(可有可无) 必须放在文件开始 • 2 import : 引入类的定义。0个或多个,必须放在所有类定义 • 之前 • 3 public class : //0个或1个,文件名必须与此类名相同。 • 4 class : //0个或多个 • interface : //0个或多个 • 程序可以有一个或多个其它类、接口(非PUBLIC类) • 一个文件中可有多个类。 • 5 main 方法: • main 的定义: public static void main(String args[]); • 位置: • 如有 public 类,则一定在此类中 • 如没有 public 类, 则可放于某一个类中。
8.6 Java的垃圾回收 垃圾回收(Garbage-collection)是Java提供的一种自动内存回收功能,可以让程序员减轻许多内存管理的负担,也减少程序员犯错的机会。