[总结]java真是博大精深(四)

来源:互联网 发布:北京市人口普查数据库 编辑:程序博客网 时间:2024/06/07 06:41

Java与面向对象技术

1、类定义

 [修饰符] class 类名[extends 父类名] [implements 接口名表] {成员变量声明;成员方法声明;}。

其中classextendsimplements都是Java的关键字。

类的修饰符:[public] [abstract] [final]

2、声明成员变量格式为:[<修饰符>]<变量类型> <变量名>;

修饰符为[public | protected | private ][static] [final] [transient ][volatile];Java类的状态用成员变量来表示。

volatile是一个类型修饰符,表示不稳定的。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。

Transient:不做串行化

3、类的行为由其方法实现,其他对象可以调用对象的方法来得到该对象的服务。类中需要定义成员方法的声明和实现。[<修饰符>] <返回值类型> <方法名>([<参数表>])[throws <异常类>]{<方法体>};

方法修饰符为:[public| protected |private][static][final | abstract] [native] [synchronized]

方法头中的参数列表(形式参数)规定了方法的输入数据,而方法的返回值是方法的输出数据。

当在方法中调用一些不是由java语言写的代码或者在方法中用java语言,直接操纵计算机硬件时要声明为native方法。

Synchronized线程的同步。

4、方法的返回值

 return  表达式;或return

5、变量的作用范围

在类中定义的变量可以在方法中直接使用。Java允许在任何一个程序块中声明变量,该变量的作用范围就是声明该变量的程序块,在作用域之外,不能访问该变量。

 方法体中声明的局部变量的作用域在该方法内部。它不是类的成员变量。

 在Java语言中,方法与变量的作用域,根据定义的位置不同,作用域也不全相同。当一个方法使用某个变量时,以如下的顺序查找变量:当前方法、当前类、各级父类、import类和包。若局部变量与类的成员变量同名,则类的成员变量被隐藏。

6、对象的声明与创建

 声明对象:类名 对象名;

实例化对象:对象名=new 类名();

声明对象的同时实例化对象:类名 对象名=new类名()

实例化对象时,系统会对成员变量进行默认的初始化。

7、对象的使用

 访问对象成员的一般形式为:对象名.成员变量名;对象名.成员方法名(),运算符”.”在这里称为成员运算符。

 使用成员变量和使用普通变量一样,只是书写格式不同罢了。成员变量必须通过对象来引用。

 如果要调用某类的方法,必须先创建该类的对象,通过这个对象调用方法。

8、对象的构造和初始化

 在用new生成对象实例时:<变量名>=new <类名>(参数表);系统自动初始化所有变量。

    步骤为:分配新对象的空间,并进行默认的初始化;执行显式的成员初始化;执行构造方法。

 显示成员初始化:在类的定义中,给出了每个成员初始值。

 构造方法:对成员变量进行初始化。

    构造方法的名字必须与类名相同。

    构造方法没有返回值,并且没有void修饰符。因为一个类的构造方法返回值应是该类本身。

    在实例化对象的时候由new运算符自动调用。对象名=new 类名(参数表);

    构造方法也是一种方法,是一个特殊的成员方法。一个类中可有多个具有不同参数列表的构造方法。

    构造方法可以拥有方法的修饰符。

    Java允许对象在创建时就初始化。而这种自动初始化是通过使用构造方法(Constructor)来实现的。系统允许程序员编写自己的构造方法完成不同的操作。

    构造方法的名字与包含它的类相同,在语法上类似于一个方法。

    若一个类没有构造方法,系统会自动为类生成一个默认的构造方法,其参数列表及方法体均为空。如果程序员在类中定义了一个以上的构造方法,则自动屏蔽掉默认的构造方法,程序员定义的构造方法中,最好包括一个参数表为空的构造方法。

   构造方法不能继承。

9、对象的销毁

 Java的垃圾回收机制自动判断对象是否在使用,并能够自动销毁不再使用的对象,收回对象所占的资源。

 程序中也可以使用析构方法finalize()随时销毁一个对象,将资源还给系统。protected void finalize() throws Throwable{…}。

    finalize方法,没有参数,也不返回值。

    一个类只能有一个finalize( )

10、类的封装

 封装(encapsulation):类的设计者把类设计成一个黑匣子,使用者只能看见类中定义的公共方法,而看不见方法的实现细节,也不能直接对类中的数据进行操作。

 封装的目的:隐藏类的实现细节;迫使用户通过接口去访问数据;增强代码的可维护性。

 访问权限

权限修饰符

同一类

同一包

不同包的子类

所有类

公有的(public

保护的(protected

 

默认的

 

 

私有的(private

 

 

 

 设置类的访问权限

    可以用public将类设置为公有的,公有类可以被其他类所访问和引用,在一个源程序中,public类只能有一个。

    可以不用权限修饰符(包访问性)。只能被同一个包中的类访问和引用。

    不允许使用public以外的权限修饰符。

 设置类中成员的访问权限

    声明类中的成员时,可以用权限修饰符来限制其他类的对象访问该成员。

    一个类作为整体对程序的其他部分可见,并不能代表类内的所有属性和方法也同时对程序的其他部分可见,前者只是后者的必要条件,类的属性和方法能否为其他类所访问,还要看这些属性和方法自己的访问控制符。

 实例变量与类变量

    static用在变量或方法前,表明它们是属于类的,称为类方法(静态方法)或类变量(静态变量)。若无static修饰,则是实例方法和实例变量。

类变量在各实例间共享。生存期不依赖于对象,相当于C语言中全局变量的作用。其它类可以不通过实例化访问它们。

    实例变量:每次创建对象时,系统都创建实例变量的拷贝。每一个对象都有一个实例变量。引用方法:对象名.实例变量

    类变量:运行时,只为该类的第一个对象分配内存单元,其后创建的所有对象都共享这一类变量。引用方法:类名.类变量;对象名.类变量。

    实例变量允许超前引用类变量;实例变量不能超前引用实例变量,静态变量不能超前引用静态变量。

 实例方法与类方法

    类方法:既可以通过对象来调用,也可以通过类名来调用。只能使用其内部定义的局部变量或类变量。目的:使方法独立于类的实例,使用类去访问。

    实例方法:实例方法只能通过对象来调用;即可以访问类变量,也可以访问实例变量。

    类方法相当于C语言中的全局函数,其他的类不用实例化即可调用它们。

    类方法不能被覆盖,也就是说在该类的子孙类中,不能有相同名称、相同参数的方法。

    实例方法中允许超前引用实例变量和类变量,类方法中只允许访问类变量,但允许超前引用。

11、包

 包(package)是Java提供的一种区别类名字空间的机制,是类的组织方式。包对应一个文件夹,包中可以再有包,称为包等级。

 同一个包中的类名不可以重复,不同包中的类名可以相同,有助于避免命名冲突。

Java中预定义了许多包,常用的有:java.lang语言包,提供Object、String等基础类;java.util实用包,提供日期类等实用类;java.awt抽象窗口工具包;java.text文本包;java.io输入输出流的文件包;java.applet Applet应用程序包;java.net网络功能包。

 创建包:package [包名1[.包名2[.[...]]]]。注意:在Java程序中,package语句必须是程序的第一条非空格、非注释语句。

    package mypackage.personmanage;这条语句指定这个包中的文件存储在目录

path/mypackage/personmanage下。包层次的根目录path是由环境变量CLASSPATH来确定的。

 导入包

    使用import语句:import包名.标识符;import包名.*;

    直接使用包:java.util.Date day=newjava.util.Date();

  Java查找类的顺序:java中对于某个类的查找是把classpath中的每一项逐一连接,当一个连接能够正确找到相关类后,便不再向后查找。类装载器装入类的次序就是类在classpath中出现的次序。类装载器从classpath的第一项开始,依次检查每一个设定的目录和压缩文件,尝试找出待装入的类文件。当类装载器第一次找到具有指定名字的类时,它就把该类装入,classpath中所有余下的项目都被忽略。

12、继承

 面向对象技术提供了继承机制,这是一种无限重复利用程序资源的途径。类继承是指一个类可以继承其他类的非私有成员,实现代码复用。被继承的类称为父类,继承父类后产生的类称为子类。

 继承的优点:代码的可重用性;父类的属性和方法可用于子类;设计应用程序变得更加简单;可以轻松地自定义子类。

 继承的特点:Object是所有类的超类;具有层次结构;子类继承了父类的非私有属性和方法;在Java语言中,只允许单继承。

 Java中的类都是Object的子类。Object类定义了所有对象都必须具有的基本状态和行为,Java中的每个类都从Object类继承了变量和方法,Java的所有对象都具有Object对象的基本状态和行为。

 object类中的方法:

    public final Class getClass();获取当前对象所属的类信息,返回Class对象。

   public String toString();返回当前对象本身的有关信息,按字符串对象返回。

   public boolean equals(Object obj);比较两个对象是否是同一对象,是则返回true

   protected Object clone();生成当前对象的一个拷贝,并返回这个复制对象。

   protected void finalize() throws Throwable;定义回收当前对象时所需完成的资源释放工作。

继承的实现

   class SubClass extends SuperClass{ …… }

   缺省extends子句,该类为java.lang.Object的子类。

   父类和子类在同一个包内:子类继承父类中权限为public、protected和包访问性的成员变量和方法;

   父类和子类不在同一个包内:父类是公有类,子类可以继承父类中权限为public、protected的成员变量和方法;否则,子类不能继承父类中的成员变量和方法。

   不能继承访问权限为private的成员变量和方法。

   构造方法不能继承。

 子类继承超类的成员变量

    如果子类声明一个与超类成员变量同名的成员变量,子类的成员变量就隐藏了超类的成员变量。

    这里的隐藏是指子类拥有了两个相同名字的变量,一个继承自超类,另一个自己定义。

    当子类执行继承自超类的方法时,处理的是继承自超类的变量。

    当子类执行它自己定义的方法时,所操作的是它自己定义的变量,而把继承自超类的变量“隐藏”起来了。

    继承是批判地继承,没有的可以增加,不需要的可以不继承。

    若子类声明了与父类同名的变量,则父类的变量被隐藏起来,直接使用的是子类的变量,但父类的变量仍占据空间,可通过super或父类名来访问。

13、多态性

 多态:一个名字可具有多种语义。在面向对象的语言中,多态是指一个方法可能有多个版本,一次方法调用,可能是这些版本中的任何一个。

 在java语言中,多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方法重写实现的动态多态性(运行时多态)。编译时多态:在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。运行时多态:由于子类继承了父类所有的属性(私有的除外),所以子类对象可以作为父类对象使用。程序中凡是使用父类对象的地方,都可以用子类对象来代替。一个对象可以通过引用子类的实例来调用子类的方法。

 方法重载指的是同一类中的相同名字的方法有多个;方法覆盖指的是父类和子类中具有相同名字的方法。重写方法的调用原则:java运行时系统根据调用该方法的实例,来决定调用哪个方法。对子类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法;如果子类继承了父类的方法(未重写),则运行时系统调用父类的方法

 方法重载

    方法的重载:一个类中有多个同名的方法带有不同的参数表。

    参数必须不同,即可以参数个数不同,也可以是类型不同;重载方法的返回值类型可以不同。

 方法覆盖

    子类可以继承父类的方法,也可以自己定义与父类的方法名、参数表及返回类型完全一致的方法,来覆盖父类的方法,即子类中的方法隐藏了父类中同名同参数表的方法。

    在子类中,若要调用父类中被覆盖的方法,可以使用super

    覆盖方法的方法名、返回类型和参数列表必须与它所覆盖的方法相同。若方法名相同,而参数表不同,则不是对父类方法的覆盖,而是对父类方法的重载。

    子类覆盖超类的方法不能比超类中定义的方法具有更严格的访问权限。

    子类不能覆盖父类中声明为final的方法。子类必须覆盖父类中声明为abstract的方法,或继续声明为abstract。

14、this引用

 指代当前对象本身格式为:this。this相当于对象的另外一个名字,利用this可以调用当前对象的方法或使用当前对象的属性。更多情况下,this用来把当前对象的引用作为参数传递给其他的对象或方法。

 访问当前对象的变量和方法,格式为:this.<成员变量名>;this.<成员方法名>。

 构造方法中调用本类的其他重载的构造方法时,应使用this,这个调用语句应该是整个构造方法的第一个可执行语句。,格式为:this (<参数列表>)。

 构造方法的形式参数与类的成员变量名相同时,需要使用this

15、super引用

 调用超类的构造方法:super(〈参数列表〉);

 父类的构造方法生成实例,super必须是子类构造方法的第一条语句。

 不允许出现同时调用父类和子类的构造方法。

 构造方法不能继承,但子类在创建对象时要对继承来自父类的成员进行初始化,因此,在创建子类时除了执行子类的构造方法外,还需要调用父类的构造方法,具体遵循原则如下:

    对于父类的含参数构造方法,子类可以在自己构造方法中使用super调用它,但super调用语句必须是子类构造方法中的第一个可执行语句。

    子类在自己的构造方法中如果没有用super明确调用父类的构造方法,则在创建对象时,将自动先执行父类的无参构造方法,然后再执行自己定义的构造方法。

    当子类未定义构造方法时,创建对象时将无条件地调用父类的无参构造方法。

 子类可以继承超类的方法,也可以自己定义与超类的方法名、参数表及返回类型完全一致的方法,来覆盖超类的方法,即子类中的方法隐藏了超类中同名同参数表的方法。在子类中,若要调用超类中被覆盖的方法,可以使用super。使用关键字super,可以引用被子类隐藏的超类 的成员变量和成员方法,称为super引用。

 访问被子类隐藏的超类的成员变量和成员方法:super.〈变量名〉;super.〈方法名〉。

 总结:super的使用可以分为下面三种情况:用来访问父类被隐藏的成员变量;用来调用父类中被重写的方法;用来调用父类的构造方法。

16、父类和子类对象之间的类型转换:子类对象可以看做是其父类的一个对象,反之不可;使用父类对象的地方,可以用子类对象来代替。

17、对象的上转型对象

 假设A类是B类的父类,class B extends A{}当我们用子类创建一个对象,并把这个对象的引用放到父类的对象中时,称这个父类对象a,是子类对象b的上转型对象。

 上转型对象可以操作子类继承或重写的成员变量,也可以使用子类继承的或重写的方法。

上转型对象不能操作子类新增的成员变量和子类新增的方法。

如果子类重写了父类的某个方法后,当对象的上转对象调用这个方法时一定是调用了这个重写的方法,因为程序在运行时知道,这个上转对象的实体是子类创建的,只不过损失了一些功能而已。

不要将父类创建的对象和子类对象的上转型对象相混淆。

若父类对象引用指向的实际是一个子类对象,则这个父类对象的引用可以用强制类型转换转化成子类对象的引用。之后就可以操作子类新增的成员变量和子类新增的方法。

方法的形参是父类对象,实参可以是子类对象。

18、instanceof 对象运算符:用来判断对象是否属于某个类的实例。若是则返回true,否则返回false。

19、方法查找

  当一个消息 (method)被发送给一个实例时,系统会在类层次树上进行查找,假设向类D的对象发送了一条消息M()。如果方法M() 在类 D中定义,则执行此方法,否则在D的父类(C)中查找此方法。如果仍未找到,则沿类的层次继续向上查找,直到Object类。可以使用super关键字来指定方法查找的开始位置。

20、final修饰符

 常量:final在变量之前,定义一个常量。

 最终方法:final在方法前,该方法不能被覆盖。

 最终类: final在类前,表示该类不能被继承。

21、抽象类

 抽象类是没有具体实例对象的类。

 抽象类不能被直接实例化。

 由abstract修饰的方法叫抽象方法,抽象方法没有方法体。

abstract type method_name(parameter_list);

 抽象方法必须声明在抽象类中。

 抽象类的子类必须实现超类中的所有抽象方法,或者将自己也声明为抽象的。

 构造方法不能声明为抽象方法。

 父类中的某些抽象不包含任何逻辑,并需要在子类中重写,子类提供这种抽象方法的实现细节。抽象类可以有构造方法,主要是子类在实例化时会调用父类的构造方法。

22、接口

 接口是一种抽象类,只包含抽象方法及常量。

接口可以实现多态,支持多重继承。

变量默认是public、static、final的,方法默认为public、abstract的。

接口(interface):是没有实现的方法和变量的集合。

定义:<修饰符>interface <接口名> { 静态常量; 抽象方法;},<修饰符>可以是public,也可省略。若声明为public,该接口可以被所有的类和接口使用;否则只能被同一包中的类和接口使用。

接口的实现

  接口一旦定义,就可以有一个或多个类来实现这个接口。

  若实现接口的不是抽象类,则该类必须实现定义在接口中的所有方法,而且方法必须声明为public

  为了实现这个接口,每个类可以自由地决定方法具体实现的细节。如果不能实现某个方法,也必须写出一个空方法。

  <修饰符> class <类名> [extends <超类名>][ implements <接口名1>,…,<接口名n>]。

  Java允许多个类实现同一个接口,也允许一个类实现多个接口。

接口的继承

  接口可以通过关键字extends继承其他接口。子接口将继承父接口中所有的常量和抽象方法。

  子接口的非抽象派生类不仅需实现子接口的抽象方法,而且需实现继承来的抽象方法。不允许存在未被实现的接口方法。

接口可以作为一种引用类型来使用。任何实现接口的类的实例都可以存储在该接口类型的变量中。通过这些变量可以访问类实现的接口的方法。Java运行时系统动态地确定应该使用哪个类中的方法。

接口和抽象类的异同

  相同:都有抽象方法,都必须在子类中实现这些方法;都不能用new关键字来创建这两种类型的对象;都可以具有继承关系;接口和类一样可以具有public属性。

  不同:在抽象类中,抽象方法必须加abstract关键字,而在接口中不需要;在抽象类中,可以定义实例变量和非抽象方法,在接口中,只能定义常量和抽象方法;接口允许多继承,类仅支持单继承。

接口的优点:接口的使用使得方法的描述说明和方法功能的分开,有助于降低程序的复杂性,使程序设计灵活,便于扩充修改。这也是Java面向对象程序设计方法中多态特性的体现。

原创粉丝点击