Java(b)--Java面向对象程序设计

来源:互联网 发布:校园网络拓扑结构图 编辑:程序博客网 时间:2024/05/16 17:13

第二部分:Java面向对象程序设计

  • 面向对象概念

  • 类与对象

  • 类的封装性,继承性,多态性

  • Java的异常处理机制

  • 包的使用

面向对象的相关性质以及概念:

计算机语言的发展历程

2

类的概念:具有相同属性相同行为的一组对象,广义地讲,类是具有共同性质的事物的集合

面向对象程序设计的三个主要特征:封装性,继承性,多态性

类的声明格式

3

(注意:类名的首字母大写,如Person)

类产生对象的一般形式:

类名对象名 = new 类名()

为了保证一个类的封装性,因此一般将变量声明为私有类型,避免对其直接修改,但是如果真正需要对其进行调用时,可以使用函数得到方法进行调用。一般将其命名格式设置为:setXxx(), getXxx();

对于私有的方法可以设置一公有方法,对公有方法的调用可以直接调用私有方法,这也是一种私有成员的类外部调用方式

匿名对象:

其是没有被明确声明的对象,某种意义上来说是只使用一次的对象,即没有任何一个具体的对象名称引用它

构造方法:

构造方法的特点是:一则为它具有与类名相同的名称,二则为它没有返回值。

其作用是对对象的数据成员做初始化的赋值

对象的比较:

对象内存地址的比较使用的是“==”,而两个对象内容的比较使用的是equals()方法

一般情况下而言,如果相同的变量类型声明的变量,那么相同的名称则会享有相同的地址,而如果采用的是new的形式,则声明的变量享有不同的地址。

对于使用第一种方法声明的变量而言,那么只有首先将其断开了所有的连接之后,才能对其空间进行修改。

This关键词的使用

理解this的一条基本原则:this表示的是当前对象

Static关键字的使用

程序中用static声明变量的话,那么该变量称之为静态变量。

在JAVA中使用的static关键字,当用来修饰类的属性时,则该属性时公共属性,无需再新建每一个对象时重复添加。我们可以通过一次修改该公共属性达到整体修改的目的。

简单应用:利用static计算产生对象的个数

5

(此处设置的计数器静态变量是全局变量,不随新对象的建立而重新进行初始化)

静态方法

注意不能用静态方法调用非静态属性

理解main()方法

main()方法前件的构成:

由于Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,又由于Java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static的why? ,该方法接收一个String类型的数组参数,该数组中保存执行Java指令时传递给所运行的类的参数。

public class TestMain {    /*    public:represent a public method    static: represent a static method that can be transferred derictly    void: there is no return value    main: system-defined method name    String args[]: receive the parameters while program is running    */    public static void main(String[] args) {        //get the length of the input parameters          int j = args.length;        if(j!=2) {            System.out.println("the parameters number is wrong!");            //exit            System.exit(1);        }        for(int i = 0; i < args.length; i++) {            System.out.println(args[i]);    //first second        }    }}

使用命令行在其编译之后运行java TestMain first second, 所有接收的参数都被存放在args[] 字符串数组之中

静态代码块

静态代码块优先于静态方法执行,而且其仅仅会执行一次,一次可以使用静态代码块为静态属性进行初始化。

对象数组的使用

对象可以使用数组进行存放,可以通过两个步骤来实现:

  1. 声明类类型的数据变量,并用new分配内存空间给数组
  2. 用new产生新的对象,并分配内存空间给它

为创建三个Person类类型的数组元素,可以使用以下三种语法:

  1. Person p[]; //声明Person类类型的数组变量

    p = new Person[3]; //用new分配内存空间

  2. p[0] = new Person(); //用new产生新的对象,并分配内存空间给它

    p[1] = new Person();

    p[2] = new Person();

  3. Person p[] = new Person[3];

    //创建对象数组元素,并分配内存空间

当然,也可以利用for循环来完成对象数组了的初始化操作,此方法属于动态初始化:

for(int i = 0; i < p.length; i++) {  p[i] = new Person();}

或采用静态方法初始化对象数组:

Person p[] = {new Person(), new Person(), new Person()};

Java文档注释

文档注释以/*开始,以 */结束。文档注释提供将程序信息嵌入到程序中的功能。开发者可以使用javadoc工具将信息取出,然后转换为HTML文件。文档注释提供了编写程序文档的便利方式。

javadoc标记

javadoc程序识别下列标记:

!7

详情参阅Java基础教程P201

file:///D:/books/book%20of%20java/Java%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B.pdf

本章摘要:

  1. “类”是把事物的数据与相关的功能封装在一起,形成的一种特殊结构,用以表达对真实世界的一种抽象概念;

  2. Java把数据成员称为field(属性),把方法成员称为method(方法);

  3. 由类所创建的对象称为instance(实例)

  4. 创建属于某类的对象,可通过下面两个步骤来达成:

    (1).声明指向“由类所创建的对象”;

    (2).利用new创建新的对象,并指派给步骤一中所创建的变量

  5. 要访问到对象里的某个属性时,可以通过“对象名称.属性”语法来实现,如果要调用封装在类里的方法,则可通过“对象名称.method”语法来实现。

  6. 有些方法不必传递任何数据给调用端程序,因此是没有返回值的。若方法本身没有返回值,则必须在方法定义语句前面加上关键字void。

  7. 私有成员可限定类中的属性,被限制成私有的属性仅能供同一个类的方法所访问。

  8. 类外部可访问到类内部的共有成员。

  9. “封装”是把属性和方法包装在一个类内以限定成员的访问,以起到保护数据的作用。

  10. 构造方法可视为一种特殊的方法,它的主要作用是为所创建的对象赋初值;

  11. 构造方法的名称必须与其所属的类的类名称相同,且不能有返回值;

  12. 从某一构造方法内调用另一构造方法,是通过this()这个关键词来完成的。think

  13. 构造方法有private和public之分。声明为public的构造方法可以在程序的任何地方被调用,所以新创建的对象都可以自动调用它。而被声明为private的则无法在该构造方法所在的类以外的其他方法被调用。

  14. 如果构造方法省略不写,Java则会自动调用默认的构造方法(默认的构造方法没有任何参数);

  15. “基本类型的变量”是指用“int”,“double”等关键词所声明的变量,而由类声明而得的变量,称之为“类类型的变量”,它是属于“非基本类型的变量”的一种。

  16. 对象也可以用数组来存放,但必须有下面两个步骤:

    (1). 声明类类型的数组变量,并用new分配内存空间给数组;

    (2). 用new产生新的对象,并分配内存空间给它。

  17. 如果在类Outer的内部再定义一个类Inner,此时类Inner称为内部类(inner class),而类Outer则称为外部类(outer class)

类的继承

super关键词的使用

super主要的功能是调用父类中的属性或方法。

用super调用父类中的构造方法,只能放在程序的第一行。

8

抽象类

9

抽象类定义的规则:

  • 抽象类和抽象方法都必须用abstract关键字来修饰
  • 抽象类不能被实例化,也就是不能被new关键字去产生对象;
  • 抽象方法只需声明,而不需实现;
  • 含有抽象方法得到类必须被声明为抽象类,抽象类的子类必须复写所有的抽象方法才能被实例化,否则这个类还是个抽象类
//this is a test file to show //the use and function of abstact class and abstact methodabstract class Person {    String name;    int age;    String occupation;    //declare an abstract method talk();    public abstract String talk();}//class Student extends class Personclass Student extends Person {    public Student(String name,int age,String occupation) {        this.name = name;        this.age = age;        this.occupation = occupation;    }    //duplicate the method talk()    public String talk() {        return "student =>> name:" + this.name + ",age:" + this.age + ",occupation:" + this.occupation + "!";    }}//class Worker extends class Person class Worker extends Person {    public Worker(String name,int age,String occupation) {        this.name = name;        this.age = age;        this.occupation = occupation;    }    //duplicate the method talk()    public String talk() {        return "Worker =>> name:" + this.name + ",age:" + this.age + ",occupation:" + this.occupation + "!";    }}class TestAbstractDemo1 {    public static void main(String[] args) {        Student s = new Student("William", 20, "student");        Worker w = new Worker("Robot", 25, "Worker");        System.out.println(s.talk());        System.out.println(w.talk());    }}//retult://student =>> name:William,age:20,occupation:student!//Worker =>> name:Robot,age:25,occupation:Worker!

10

如果抽象类中有构造方法,那么在子类中必须调用该构造方法:

因此可以在子类的构造方法中使用super:

super(name,age,occupation);

Object 类

Object类是所有类的父类,如果一个类没有用extends关键字明确标识继承另外一个类,那么这个类就默认继承Object类。

Object 类是Java内层中的最高层类,是所有类的超类。换句话说,Java中任何一个类都是它的子类。由于所有的类都是由Object类衍生出来的,所以Object类中的方法适用于所有类。

toString() 方法

如果对于一个对象实例的直接调用,那么实际上调用的是Object类中的toString()方法,因此可以通过复写toString()方法来控制输出的内容:

System.out.println(p) = System.out.println(p.toString());

final 关键字

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

  1. final标记的类不能被继承;
  2. final标记的方法不能被子类复写;
  3. final标记的变量(成员变量或局部变量)即为常量,只能赋值一次。

*接口(interface)

接口的结构与抽象类非常相似,也具有数据成员和抽象方法,但它与抽象类又有以下两点不同:

  1. 接口里的数据成员必须初始化,且数据成员均为常量;
  2. 接口里的方法必须全部声明为abstract,也就是说,接口不能像抽象类一样保有一般的方法,而必须全部是抽象方法。

    Screensho

利用接口打造新的类的过程,称之为接口的实现(implementation)

Screenshot2

Screenshot3

多态性

多态性有两个极为重要的概念:向上转型向下转型

此概念较为难以理解,之后再进行深入分析

注:向上转型可以自动完成,向下转型必须进行强制类型转换

instanceof 关键词的使用

可以用instanceof判断一个类是否实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。

instanceof 的语法格式为:

对象 instanceof 类(或接口)=》返回值是boolean

class Person {    private String name;    private int age;    public Person(String name,int age) {        this.name = name;        this.age = age;    }    //override equals() in Object    public boolean equals(Object o) {        boolean temp = true;        //declare an object which has transferred equals() in reality        Person p1 = this;        //judge whether o is an instanceof Person        if(o instanceof Person) {            //if is, downcast            Person p2 = (Person)o;            //transfer equals() of String            if(!(p1.name.equals(p2.name) && p1.age==p2.age)) {                temp = false;            }        } else {            //if o is not an instanceof Person, then return false            temp = false;        }         return temp;    }}class TestOverEquals2 {    public static void main(String[] args) {        Person t_p1 = new Person("William", 20);        Person t_p2 = new Person("William", 20);        System.out.println(t_p1.equals(t_p2) ? "same" : "different");    }}

接口对象的实例化

接口是不能被直接实例化的,但是其可通过其子类进行实例化

接口在实际使用的一个很大的作用就是定义除了一个统一的标准。

本章摘要

  1. 通过extends关键字,可将父类的成员(包含数据成员与方法)继承到子类;

  2. Java在执行子类的构造方法之前,会先调用父类中无参的构造方法,其目的是为了对继承自父类的成员做初始化操作;

  3. 父类有数个构造方法时,如要调用特定的构造方法,则可在子类的构造方法中,通过super() 这个关键字来完成;

  4. this() 是在同一类内调用其他的构造方法,而super() 则是从子类的构造方法调用其父类的构造方法think

  5. this() 除了可用来调用同一类内的其他构造方法,如果同一类内”实例变量”与“局部变量”的名称相同时,也可利用它来调用同一类的“实例变量”;

  6. this() 与super() 其相似之处:

    • 当构造方法有重载时,两者均会根据所给予的参数的类型与个数,正确地执行相对应的构造方法;
    • 两者均必须编写在构造方法内的第一行,也正是这个原因,this() 和 super() 无法同时存在同一个构造方法内。
  7. “重载”(overloading),它是指在相同类内,定义名称相同,但参数个数或类型不同的方法,因此Java 便可根据参数的个数或类型调用相应的方法;

  8. “复写”(overriding), 它是在子类中,定义名称、参数个数与类型均与父类相同的方法,用以复写父类中的方法;

  9. 如果父类的方法不希望子类的方法来复写它,可在父类的方法之前加上”final” 关键字,如此该方法便不会被复写;

  10. final的另一个公用是把它加在数据成员变量前面,如此该变量便成了一个常量,如此便无法再程序代码中再做修改了;

  11. 所有的类均继承Object类;

  12. 复写Object 类中的equals() 方法可用来比较两个类的对象是否相等;

  13. Java 可以创建抽象类,专门用来当做父类。抽象类的作用类似于”模板”,其目的是根据其格式来修改并创建新的类;

  14. 抽象类的方法可分为两种:一种是一般的方法,另一种是以abstract关键字开头的抽象方法。抽象方法并没有定义方法体,而是要保留给由抽象类派生出的新类来定义;

  15. 利用父类的变量数组来访问子类的内容较好的做法是:

    (1). 先创建父类的变量数组;

    (2). 利用数组元素创建子类的对象,并以它来访问子类的内容

  16. 抽象类不能直接用来产生对象;

  17. 接口的结构和抽象类非常相似,它也具有数据成员与抽象方法,但它与抽象类有两点不同:

    (1) 接口的数据成员必须初始化;

    (2) 接口里的方法必须全部都声明称abstract

  18. 利用接口的特性来打造一个新的类,成为接口的实现(implementation)

  19. Java并不允许多重继承;

  20. 接口与一般类一样,均可通过扩展的技术来派生出新的接口。原来的接口成为基本接口或父接口:派生出的接口成为派生接口或子接口。通过这种机制,派生接口不仅可以保留父接口的成员,同时与可以加入新的成员以满足实际的需要;

  21. Java对象的多态性分为向上转型(自动)、向下转型(强制);

  22. 通过instanceof 关键字,可以判断对象属于哪个类或者某个接口是否实现;

  23. 匿名内部类的好处是可利用内部类创建不具有名称的对象,并利用它访问到类里的成员。

异常处理

异常的基本概念

常见的异常(程序运行时发生的、会打断程序正常执行的操作)

  1. 算术异常(Arithmetic Exception)
  2. 没有给对象开辟内存空间时会出现空指针异常(Null Pointer Exception)
  3. 找不到文件异常(File Not Found Exception)

Java的异常处理机制也秉持着面向对象的基本思想。在Java中,所有的异常都是以类的类型存在的,除了内置的异常类之外,Java也可以自定义异常类。而且可以自定义抛出异常。

为何会有异常处理机制:

在没有异常处理的语言中,就必须使用if或switch等语句,配合所想得到的错误情况来捕捉程序里所有可能发生的情况。但是为了捕捉这些情况,编写出来的程序代码经常有很多if语句,有时候这样也未必能捕捉到所有的错误,而且这样做势必导致程序运行效率降低。

Java的异常处理机制恰好改进了这一点。它具有易于使用、可自行定义异常类,处理抛出的异常同时又不会降低程序运行的速度等特点。因此在Java程序设计时,应充分地利用Java的异常处理机制,以增进程序的稳定性及效率。

Screenshot4

该语法的执行顺序:

  1. try程序块若是有异常发生时,程序的运行便中断,并抛出“异常类所产生的对象”;
  2. 抛出的对象如果属于catch() 括号内欲捕获的异常类,则catch会捕捉此异常,然后进到catch的块里继续运行;
  3. 无论try程序块是否有捕捉到异常,或者捕捉到的异常是否与catch()括号里的异常相同,最后一定会运行finally块里的程序代码。

    异常类的继承架构

Screenshot5

自定义异常类

Screenshot6

本章摘要:

  1. 程序中没有处理异常代码时,Java的默认异常处理机制会做下面的操作:

    先抛出异常,再停止程序运行

  2. 异常处理是由try、catch、finally三个关键字所组成的程序块,其语法可以参考格式一

  3. try程序块中若有异常发生时,程序的运行便会中断,抛出”由系统类所产生的对象”,并以下列的步骤运行:

    • 抛出的对象如果属于catch()括号内所要捕捉的异常类,catch会捕捉此异常,然后进到catch程序块里继续执行
    • 无论try程序块是否捕捉到异常,也不管捕捉到的异常是否与catch()括号里的异常相同,最后都会运行finally块里的程序代码。
    • finally中的代码时异常的统一出口,无论是否发生异常都会执行此段代码
  4. 当异常发生时,有两种处理方式:

    • 交由Java默认的异常处理机制去处理
    • 自行编写try-catch-finally块去捕捉异常
  5. 异常可分为两大类:java.lang.Exception 与 java.lang.Error

  6. RuntimeException 可以不编译异常处理的代码,依然可以编译成功,它是在程序运行时才有可能发生的,而其它的Exception一定要编写异常处理的程序代码才能使程序通过编译;

  7. catch()括号内,只接收由Throwable 类的子类所产生的对象,其它的类均不接收;

  8. 抛出异常有下列两种方式:

    • 在程序中抛出异常
    • 指定方法抛出异常
  9. 程序中抛出异常时,要用到throw这个关键字

  10. 如果方法会抛出异常(使用throws), 则可将处理此异常的try-catch-finally块写在调用此方法的程序代码中。

包与访问权限

包的概念及使用

package是在使用多个类或接口时,为了避免名称重复而采用的一种措施。那么具体应该怎么使用呢?在类或接口的最上面一行加上package的声明就可以了。

package package 名称;

package demo.java;class Person {    public String talk() {        return "Person =>> talk()";    }}class TestPackage1 {    public static void main(String[] args) {        System.out.println(new Person.talk());    }}

编译: javac -d.TestPackage1.java

(-d:表示生成目录;”.”表示在当前目录下生成)

执行:java.demo.java.TestPackage1

import语句的使用

package的导入:

import package 名称.类名称;

通过import命令,可将某个package内的整个类导入,后续的代码便不用再写上被访问package的名称了。

可以将import demo.java.a.Person 改成import demo.java.a.*,表示导入包中的所有类,在java中有这样的规定:导入全部类或是导入制定的类,对程序的性能没有影响,所以在开发中可以直接写导入全部类,而且此方法较为方便。 Screenshot7

类成员的访问控制权限

在JAVA中有四种访问控制权限,分别为:private、default、protected、public

private 访问控制符

如果一个成员方法或成员变量名前使用了private访问控制符,那么这个成员就只能在这个类的内部使用;

注意:不能在方法体内声明的变量前加private修饰符。

默认访问控制符

如果一个成员方法或成员变量名前没有使用任何访问控制符,就称这个成员所拥有的是默认的(default) 访问控制符。

默认的访问控制成员可以被这个包中的其他类访问。但如果一个子类与其父类位于不同的包中,子类也不能访问父类中的默认访问控制成员。

protected访问控制符

如果一个成员方法或成员变量名前使用了protected访问控制符,那么这个成员既可以被同一个包中的其他类访问,也可以被同一包中的子类访问。

public访问控制符

如果一个成员方法或成员变量名前使用了public访问控制符,那么这个成员可以被所有的类访问。不管访问类与被访问类是否在同一个包中。

Screenshot9

Java命名习惯

  • 包名中的字母一律小写,如demo.java
  • 类名、接口名应当使用名词,每个单词的首字母大写,如:TestPerson;
  • 方法名:第一个单词小写,后面每个单词的首字母大写,如talkMySelf();
  • 常量名中的每个字母一律大写,如:COUNTRY

本章摘要

  1. java中使用包可以实现多人协作的开发模式
  2. 在java中使用package关键字来将一个类放入一个包中;
  3. 在java中使用import语句,可以导入一个已有的包;
  4. java中的访问控制权限分为四种:private、default、protected、public
  5. 使用jar命令可以将一个包打成一个jar文件,供用户使用
1 0