首页 > 代码库 > Java笔记十四.深入理解类和对象(1)

Java笔记十四.深入理解类和对象(1)


    Java是一种完全面向对象的编程语言(C是面向过程)。所谓面向对象编程(OOP),即是一种编程风格,它通过给程序中加入扩展语句,把函数“封装”进编程所必需的“对象”中。OOP 达到了软件工程的三个主要目标:重用性、灵活性和扩展性。其实,面向对象就是把一切东西看成一个个对象,比如人,车,面包,等等,然后把这些对象拥有的属性变量,比如年龄,民族,工作地点,变质期,寿命,还有操作这些属性变量的函数(方法)打包成一个类来表示,这个类的一个抽象就是一个对象。在Java程序中,一般通过变量描述其状态,通过方法描述其行为。所以,对象普遍具有的特征是:状态和行为,也可以表示为相关数据(状态)和方法(行为)的集合。

一、基本概念

    面向对象程序设计中的概念主要包括:类、对象、数据抽象、继承、数据封装、多态性、消息传递、接口。通过这些概念面向对象的思想得到了具体的体现。
1.类:
   关键词:class.具有相同特性(数据元素)和行为(功能)的对象的抽象(集合)就是类。通过类可以生成一个有特定状态和方法的实例,即实例对象。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。比如小花是人类中的一个,人类有很多共同的特性(指状态和行为),但是小花和其他人除了拥有人类共有的特征外还具有其自身的特征,所以小花是人类的一个实例对象。Java编程就是设计类,即在编程中可以采用自定义方法或者继承某个类的方法设计一个类,然后用它的实例对象更改类的状态和行为来实现具体功能。
2.对象:
    对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。一个对象有状态、行为属性。在Java编程中,通过实例对象改变类的状态和行为来实现具体的功能。
(1)对象具有状态:一个对象用数据值来描述它的状态;
(2)对象还有操作(行为):用于改变对象的状态,对象及其操作就是对象的行为。 对象实现了数据和操作的结合,使数据和操作封装于对象的类中。
笔记:类是对某一类事务的描述,是抽象的、概念上的定义;对象是实际存在的该类事务的个体,因而也称实例。可见,类描述了对象的属性和对象的行为。
3.封装:
    封装就是将相关数据和方法放在一个包里,其作用就是把类设计成一个黑箱子,使用户看得见类具有的公共方法,看不到方法实现的的细节,也不能直接对类的数据进行操作。封装使程序具有模块化和数据隐藏的特性。
笔记:封装就是将类的成员变量声明为私有的(private),在提供一个或多个公有(public)方法实现对该成员变量的访问或修改。实现封装可以达到如下目的:
(1)隐藏类的实现细节;
(2)让使用者只能通过实现定制好的方法来访问数据,可以方便地加入控制逻辑,限制属性的不合理操作;
(3)便于修改,增强代码的可维护性;
(4)可进行数据检查。
4.消息:    
    单独一个对象的功能是有限的,OOP使用消息传递机制来实现对象之间的联系。消息传递机制包含3个要素:事件源、事件监听器、事件对象。其中,事件监听器是连接对象的关键,它在对象之间传递消息并调用事件处理对象的方法处理事件
5.继承:
    关键词:extends。OOP允许由一个类来定义另外一个类,这个类我们称之为该类的子,子类继承了父类的状态(成员变量)和行为(成员函数)。除此之外,子类还可以添加新的变量和方法,使其有自己的功能;子类还可以覆盖(override)继承下来的方法来实现特殊要求。比如山地车都属于自行车,他们是自行车的子类,除了拥有自行车的共同特性,还拥有自身的特点.继承是父类的代码得到重用,在继承父类提供的共同特性的基础上添加新的代码,是编程不必一切从头开始,Java的继承性有效地提高了编程效率。
6.接口:
    关键词:implements。接接口是为了解决Java语言中不支持多重继承问题而产生,也就是说Java不支持多继承,子类智能有一个父类。接口可视为特殊的类,它具有一些公用的常量和常用的方法(方法可以是空方法)。Java用过引用接口来使用个其中公用的常量和方法,一个类可以实现多个接口,并用逗号隔开。Java通过接口事件了多重继承的功能。
举例:定义一个类,使其继承Applet类和ActionListener接口
public class Example extends Applet implements ActionListener
{
    ......成员变量
    ......成员函数
}
7.包:
    Java系统包,通过import关键字引入,包中实现了很多类。只有引入类所属的包才能在Java程序中,继承或使用相应的类
举例:
    import java.apple.Applet 引入applet包中的Applet类
    import java.awt.* 引入awt包中的所有类

二、类与对象

    类是具有相同特性(数据元素)和行为(功能)的对象的抽象(集合),Java程序的所有数据类型都是用类来实现的。对象(具体)是类(抽象)的实例,Java程序中使用标识符(如Button button)表示对象,通过对象引用类中的变量和方法,进而实现不同的功能。类主要由成员变量、成员方法组成,通过对象引用。
1.创建类-关键字class
    [类的修饰符] <class> <类名> <extends 父类名> [implements 接口名]
    {
        <类体(成员变量和成员方法)>
    }
其中,[]表示为可选项,<>表示为必选项。
类的修饰符
-public(公共类)可以被任何包中的类访问,在同一个源程序中只能有一个public类;
-private(私有类):只能被该类的对象访问,其子类不能访问,更不能垮包访问;
-protect(保护类):能被该类对象与子类访问,即使子类在不同的包中也可以;
-default(默认类):与没有任何修饰符相同,类智能被同一个包中的其他类访问;
-abstract(抽象类):说明这个类是抽象的,不能用来创建实例对象,可以被用来继承,由继承它的子类来创建对象;
-final(最终类):最终类与abstract相反,它不能被继承,可以创建对象。最终类有利于提高系统的安全性,Java中的String类就是一个最终类。
说明:对于上述所说的对类的访问,即主要是通过对象来引用被继承的类。也就是说,要想访问一个类,首先我们要使自定义的类继承它(如果可以继承的话),如果是其他包中的类我们还需要需要通过包引入(import java.apple.Applet 引入applet包中的Applet类),然后实例化被继承类一个对象,通过这个对象引用被继承类中的方法和变量。
举例:
import java.awt.Button
public class Example extends Applet implements ActionListener
{
    ......成员变量
    ......成员函数
    Button button=new Button();
    button.xxxxx;    
    /*这里的button,为Example类的一个成员变量,它既可以引用Button类中的方法又可以使用Example类中的方法*/
}
     总结:子类除了可以直接使用父类的数据和方法外,可以有自己的数据和方法。
2.创建对象
(1)构造方法
    构造方法不是成员方法且无返回值,不能在程序中直接调用,只能由new操作符调用。其作用就是确定类成员变量的构成或者为成员变量赋初值,即对于成员变量的定义和赋值都在构造函数中实现。在类实现过程中,可以无构造方法,当我们在创建对象时,使用的就是该类默认的构造方法。在同一个类中,可以定义多个构造方法即函数名相同而参数不同。
    public class Example extends Applet implements ActionListener
{
  Example()//不带参数的构造函数
  {
int x=0;
int y=0;
  };
  private int xPos,yPos,x,y;
  Example(int x,int y)//带参数的构造函数
 { 
xPos=x;yPos=y; 
  }
}
两种形式构造方法:
第一种:不带参数的构造方法,它直接把Example类中的2个成员变量赋值为0(如果为boolean型为false,String型为null)。没有参数的构造方法是系统默认的构造方法,如果没有定义,系统将自动赋值。
第二种:带参数的构造方法,Example(int x,int y)定义了2个整型参数,实例化对象时要传递2个整型参数据给Example类赋初值

(2)创建对象
    new成为操作符,它的任务是实例化对象同时调用类的构造方法完成新建实例对象的初始化任务
    创建一个对象有3个步骤:声明对象,实例化,初始化。
a.声明对象
    <类名> <对象名>    举例:Button button;
b.实例化、初始化
    <对象名>=new <构造方法名>([参数列表]),其中参数列表为可选项。
除此之外,可以一步到位:
                <类名> <对象名>=new <构造方法名>([参数列表])
c.对象的使用
   对象被实例化后,通过对象可以引用相应类的成员变量,可以调用类的方法进行操作实现特定的功能。创建对象时,对象的所有变量和方法代码都被读到专为它开辟的内存区域中。
    <对象名>.<变量名>
    <对象名>.<方法名>  其中“.”的作用是为了让解释器知道这些变量和方法代码的内存地址。
d.对象清除
    Java引入了内存管理机制,由Java虚拟机担任垃圾收集器的工作。

总结:实例化对象作用:是为对象分配内存,由new操作符根据构造方法决定新建对象分配多大的内存来存储对象。new操作符需要一个参数,就是类的构造方法,构造方法是用于初始化对象的特别方法。new操作符为对象分配内存后将调用类的构造方法确定对象的初始状态(即为类的成员变量赋初值)。

3.成员变量
    成员变量描述了类和对象的状态,成员变量可以是不同类型的变量或者对象,对成员变量的操作实际上就是改变类和对象的状态,使之满足程序的需要。成员变量也有很多修饰符,用来控制对成员变量的访问,实现对类和对象的封装。
(1)成员变量的声明
    成员变量的声明必须放在类体中,一般是成员方法之前。这里需要注意区别成员变量局部变量。所谓局部变量,即指在方法中声明的变量,不能称之为成员变量,因为它是方法的局部变量而已。
public class Time
{
    private int x;//1.定义一个整型成员变量
    Button button;//2.定义一个对象成员变量
    Time()        //构造函数
    {
        private float y;//3.构造方法中的局部变量,不是成员变量
    }
}
注意:如果在类中定义一个对象成员变量,则这个成员变量不仅可以访问当前类的所有方法和变量,还可以访问所属类的方法或变量。
(2)成员变量的修饰
    [public][private][protected][package]    //访问修饰符
    [static][final][transient][volatile]   <数据类型>  <成员变量名称>
-public:公共变量,可以被任何包中的任何类访问(即所有包和类),不具有数据保护功能
-private:私有变量,只能被声明它的类所使用,拒绝任何外部类的访问,包括子类,具有最好的保护功能
-protected:受保护变量,只能被声明它的类和派生的子类,以及同一个包中的类访问
-package:包变量,在声明时常常省略package关键字,即没有修饰符的成员被视为包变量。包变量允许被声明它的类和同一个包中的类使用,不能被声明类的子类使用。
    如:static int x;int y;都属于包变量。
-static:static声明的成员变量被视为类的成员变量,可以直接通过类名或实例对象使用。即静态变量是固有的,可以直接使用;非静态变量,仅仅在被声明和生成实例对象才存在,才可以被引用。
-final:成员变量被声明为final,即为常量.常量和直接量一样不占用内存空间
-transient:说明成员变量不允许被序列化
-volatile:声明成员变量为易失变量,用来防止编译器对该成员进行某种优化

总结1:如果在类中定义一个对象成员变量,则这个成员变量不仅可以访问当前类的所有方法和变量,还可以访问所属类的方法或变量。
总结2:静态变量成为类变量,非静态变量成为实例变量;静态方法成为类方法,非静态方法成为实例方法。
总结3:(1)类的静态变量可以直接引用,类的静态变量相当于某些程序语言的全局变量;
       (2)静态方法只能使用静态变量,不能使用实例变量;
       (3)类的静态变量只有一个版本,所有实例对象引用的都是同一个版本。
       (4)非静态变量:对象实例化后,每个实例变量都被制作为一个副本,实例变量之间互不影响。
4.成员方法
   对象的行为由类的方法实现,其他对象可以调用一个对象的方法,通过消息的传递是实现对该对象行为的控制,类的设计集中体现在成员方法的设计上。 
(1)成员方法声明
 [public][private][protected][package]    //访问修饰符
 [static][final][abstract][native][synchronized][void]
  返回值类型 方法名(参数表) [throws 异常类型]
注意:4种访问权限和成员变量的修饰符有相同的作用。静态方法体中智能访问静态变量,静态方法可以通过对象调用也可以通过类名来调用。 
-final:最终方法。被声明为final的方法,不能被子类覆盖,即能被子类继承和使用,但不能在子类中修改或者重新定义它
-abstract:抽象方法。抽象类不能被继承,但可以定义一个拥有共同的状态和行为的统一编程接口;抽象方法无具体内容,需在子类中覆盖以实现具体的细节。注意:一个抽象类不一定非要包含一个抽象方法,但是一个类中如果有一个抽象方法就必须声明为抽象类。一个子类如果没有实现分类中的抽象方法,也必须声明为抽象类。
-native:本地方法。SDK提供了Java本地接口JNI,使得Java虚拟机能运行嵌入在Java程序中的其他语言代码
    class HeelWorld{
        public native void display();//为C语言编写程序实现这个方法
        ...
        public static void main(String[] args)
        {.....}
    }
-void:Java要求一个方法必须声明他的返回值类型,void为空类型
    public int getX();    //返回值为int类型
    void setXY();    //无返回值
    pulic Object clone();    //该方法返回值为Object类

(2)方法的参数传递
    在参数表中要声明参数的类型,并用逗号分隔多个参数。一个对象和外部交换信息的主要靠方法的参数来传递,可传递的参数包括基本数据类型、数组和对象。通过传递对象调用其方法传递参数时需要现有包含调用方法的类,然后才能穿件类的对象,调用其方法传递参数。

Java笔记十四.深入理解类和对象(1)