第五讲 类的封装和类的继承

主要内容

软件包的创建和使用

Java访问权限修饰词

类的访问权限修饰词

Java中类的层次结构和类的继承

对象的初始化再讨论

 

软件包的创建和使用

什么是软件包(package)

包的组成:由一组类(class)和接口(interface)组成。

Java允许把多个类收集在一起成为一组,称作包(package)。

 
  第五讲 类的封装和类的继承


包的作用:包是Java提供的一种类库的封装机制。专有的名字空间,解决了不同包中的类同名的问题。使自己的任务和其他人提供的代码库相分离。

 

软件包的建立

从示例程序理解

编译如下程序,查看所编译文件的位置。

package mylib.simple;

public class List{

   public List(){

        System.out.println("mylib.simple.List");

   }

}

结论

1、包对应着文件系统的目录层次结构。

2、编译生成的字节码文件将置放到包中,即包名所指定的目录中。

 

软件包的创建

package packagename;

几个要点:

package语句必须是文件中的第一条语句。

用“.”作为分隔符来指明包(目录)的层次。

包名由小写字母组成。

没有注明放入到某个包中去的类,自动地归在一个无名包中

 

软件包的使用

设置环境变量classpath

在Jcreator中添加classpath

使用如下两种方法之一:

² 用import加载包中的类:import 包名; import 包名.类名;

² 直接用包名.类名去访问类

 

说明

² import语句必须放在package语句和类的定义之间。

² 某个类若用到其他类,会优先在所在软件包中查找,继而在classpath指定的路径下查找。

 

例:创建一个newjw目录,在此新目录下创建如下java文件。

import mylib.simple.List;

class TestList{

   public static void main(String[] aa){

        new List();

   }

}

试用方法二改写并编译执行之。

思考

1.   一个程序的首语句是package a.b.c.d;其意是?

2.   一个程序中可含多个类,它们可分放到不同的软件包吗?

3.   若要使用d:\java07下的软件包,classpath如何设置?

4.   如何用到不同目录下的软件包myclass.lib1中的类?

5.   同一个软件包中的类可否直接使用?

6.   一个类设计成可被到处使用,应声明为public类吗?

7.   一个类用到其他类时,编译时的类查找路径是?

 

软件包的操作练习

练习:建立工具包,并使用之。

1. 设计一个P类置入mylib.tools包中,该P类含rint和rintln方法,可实现字符串的输出。

2. 用mylib.tools中的类P,分别输出字符串和数字。

import                         ;

class TestP{

   public static void main(String[] aa){

 

 

   }

}

3. 创建一个Input类,含有来输入整数或字符串的方法,以使下面的程序能正确编译和执行。

import mylib.tools.Input;

import mylib.tools.P;

class TestInput{

   public static void main(String[] aa){

        int y=Input.aInt();

        P.rintln(y+"");

        String s=Input.aString();

        P.rintln(s);

   }

}

练习

1. 分别构造一个Circle类和Square类,可接受半径(边长),包含求面积的方法。将它们放在myclass.simple包中。

2. 利用上述类,求半径为4.5的圆面积,边长为4.5和6.5的矩形面积。

 

Java访问权限修饰符

决定类成员的访问权限的修饰符有:public 、protected 、private。

权限的设定对于类的封装有着重要的意义。公开需要公开的,隐藏必须隐藏的。这样就让类的继承变得简单。

 

无权限修饰符的成员

允许本类、同一软件包中的类访问即享受“包访问权限”。

 

public成员

public描述的是一个类中可向外公开的信息(属性和方法)。

允许本类、继承类、同一软件包中的类、不同软件包中的类访问。

示例:不同软件包之间一个类访问另一个类的public成员。

package mylib.lib1;    //Base.java

public class Base{

   public int x=5;

   public void print(){

        System.out.println("base"+x);//本类访问

   }

}

 

package mylib.lib2;    //Derive.java

class Derive {

   public static void main(String args[]){

        mylib.lib1.Base b = new mylib.lib1.Base();

        b.x=5; //不同软件包的类访问

        b.print();

   }

}

思考

1.   程序编译后,磁盘上新增的目录结构?

2.   Base类中,可以公开的信息是?

3.   public的公开范围?

4.   如果Base类中的成员变量x前无public,会在何环节产生问题?

 

 

private成员

private修饰的成员变量和成员方法都只能在本类中访问

修饰不希望被其它类访问的变量和方法。有两种限制:

² 其它类中的该类对象不能访问private成员。

² 派生子类时,子类不能继承父类的private成员

class Base1{

   private int x=1;

   private void print(){

        System.out.println("base"+x);

   }

   void doprint(){

        print();

   }

}

class Derive1{

   public static void main(String args[]){

        Base1 b = new Base1();

        b.doprint(); //直接调用b.print();试试!

   }

}

观察JCreator中的数据视图(ctrl+alt+c),加深对private成员的认识。

 

假如构造方法是private的,类就不可直接实例化成对象:

class Sundae{

   private Sundae(){

        System.out.println("Here is a sundae");

   }

   static Sundae getASundae(){

        return new Sundae();

   }

}

class TestSundae{

   public static void main(String[] aa){

        Sundae s=Sundae.getASundae();

   }

}

protected成员

这是受保护成员。其修饰的数据和方法对继承它的子类公开。

protected成员允许本类、继承类和同一软件包中的类访问

包权限访问

class Base1{

   protected int x=1;

   protected void print(){

        System.out.println("base"+x);

   }

}

class Derive1{

   public static void main(String args[]){

        Base1 b = new Base1();

        b.print();

   }

}

继承类对protected成员的访问

package mylib.simple;//Cookie.java

public class Cookie{

   public Cookie(){

        System.out.println("Cookie constructor");

   }

   protected void bite(){System.out.println("bite");}

}

 

import mylib.simple.Cookie; //Chocolatechip.java

class Chocolatechip extends Cookie{

   Chocolatechip(){

        System.out.println("Chocolatechip");

   }

   public static void main(String[] aa){

        Chocolatechip c=new Chocolatechip();

        c.bite();    

   }

}

思考

1.   何谓类的封装?

2.   从封装角度比较以上不同的权限修饰?

3.   一个public成员向谁公开信息?

4.   一个protected成员向谁公开信息?

5.   一个private成员向其它类公开信息吗?

6.   private有何意义?

 

练习:试填表说明不同访问修饰符的访问权限

访问修饰符

本类

同软件包

不同包中子类

不同包且无继承

public

 

 

 

 

protected

 

 

 

 

无修饰词

 

 

 

 

private

 

 

 

 

 

类的访问权限

无访问修饰符

即为缺省类。可以被同一个软件包中的类访问。

 

public

通过import导入(配合classpath的设置),可以被任何其它的类访问。

public class 类名

思考

假如某一程序中定义了一个public类,框架如下:

package mylib.abc;

public class Abc{…}

 

1.   该程序应命名为?

2.   在另一个程序中如何能访问到Abc类?

3.   如果该类有显式的构造方法,并允许在其它类中创建该类的对象,构造方法的权限设置应是?

 

private类

专用于修饰内部类,内部类常用于处理本类中的事件。

 

类的继承

第五讲 类的封装和类的继承

类的层次结构

指的是继承关系可以层次地递延下去。

在Java程序中创建的所有类都是类层次结构的部件

每个类都有父类

如果没有使用extends关键字,则Object类就是缺省的父类。

Object类包含在java.lang包中。所有的类都是从这个类继承而来的。

Object类定义和执行了在Java系统需要的所有类的行为。

 

类的层次结构图

第五讲 类的封装和类的继承

 

思考

 

1.   根据层次结构图,每个类都有父类吗?

2.   如果类定义时无extends部分,该类的父类是?

3.   多个子类可以继承自一个父类吗?

4.   一个类可以同时继承多个父类吗?

5.   Object类在哪个软件包中?

 

 

类的继承(inheritance)

使用extends关键字实现继承

class SubClass extends SuperClass {

    ClassBody

}

 

父类和子类

继承另一个类的类称为子类,被继承的类称为父类。

在Java中一个类只能直接继承一个父类。

 

 

继承的意义

一个类能从其它类继承行为与属性。

 

例:通过对Person类的继承,定义Children类

class Person{

 int salary;

 void employed(){

       System.out.print("Work state:");

       if (salary==0) System.out.println("no job");

       else System.out.println("job");

 }

}

class Children extends Person{

 int age;

 void printAge(){

       System.out.println("Age:"+age);

 }

}

 

class Test{

 public static void main(String[] aa){

       Children c=new Children();

       c.salary=560;

       c.age=12;

       c.printAge();

       c.employed();

 }

}

思考

1.   一个类如何去继承另一个类?

2.   示例中Children继承了Persons类的什么?

3.   Children的实例化对象与Persons的实例化对象区别在哪里?

4.   若希望父类中的某成员不被子类所继承,如何实现?

 

练习:阅读和分析程序,理解继承。

import javax.swing.*;

class Test extends JFrame{

 public static void main(String[] aa){

       Test t=new Test();

       t.setVisible(true);

       t.setSize(300,200);

 }

}

 

对象的初始化再讨论

基本的初始化过程

² 初始化时涉及到成员变量和构造方法;

² 实例变量的初始化在构造方法之前。

class Tag{

   Tag(int m){

        System.out.println("Tag("+m+")");

   }

}

class Card{

   Tag t1=new Tag(1);

   Card(){

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

        t3=new Tag(33);

   }

   Tag t2=new Tag(2);

   void f(){

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

   }

   Tag t3=new Tag(3);

}

class TestInit2{

   public static void main(String[] aa){

        Card t=new Card();

        t.f();

   }

}

 

静态变量的初始化

类中的静态成员变量的初始化在编译时进行

静态变量只初始化一次

class Bow{

 Bow(int m){

       System.out.println("Bow("+m+")");

 }

 void f(int m){

       System.out.println("f("+m+")");      

 }

}

class Table{

 Bow b1=new Bow(1);

 Table(){

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

       b2.f(1);

 }

 static Bow b2,b3;

 static{

       b2=new Bow(2);

       b3=new Bow(3);

 }   

}

class TestInit{

 public static void main(String[] aa){

       System.out.println("Creating new Table()");

       new Table();

       System.out.println("Creating new Table()");

       new Table();

 }

}

 

思考

1. 对象的初始化在什么时候进行?

2. 静态变量和实例变量的初始化时机?

3. 实例变量和构造方法哪个先初始化?

4. 除了构造方法外,通常的成员方法会自动初始化吗?

5. 类有多个成员变量,这些变量的初始化顺序?

 

带有继承时的初始化过程

² 静态变量初始化

² 运行父类的无参数构造方法(按级别高到低)

² 本类实例变量初始化

² 运行本类的构造方法

class GrandParent{

 GrandParent(){

       System.out.println("GrandParent");

 }

}

class Parent extends GrandParent{

 Parent(){

       System.out.println("Parent");

 }

}

class Children extends Parent{

 Children(){

       System.out.println("Children");

 }

 public static void main(String[] a){

       new Children();

 }

}

问题:若类GrandParent类定义如下,程序运行结果?

class GrandParent{

 GrandParent(){}

 GrandParent(String s){

       System.out.println("GrandParent "+s);

 }

}

思考

1. 对象的初始化时,父类的什么样的构造方法能自动执行?

2. 父类构造方法的执行时机?

 

有关对象初始化的结论

继承时,初始化的顺序(包括构造方法):

主类中的静态成员初始化

运行父类的默认构造方法

(按级别高到低的顺序)

主类中非静态成员初始化

调用主类的构造方法

 

 

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-05
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-02-18
  • 2021-12-11
  • 2022-12-23
相关资源
相似解决方案