-
面向对象程序设计(OOP)概述
面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐藏的实现部分。
(1)类
类(class
)是构造对象的模板或蓝图。由类构造(construct
)对象的过程称为创建类的实例(instance
)。
Java
编写的所有代码都位于某个类的内部。
封装:把数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式。对象中的数据称为实例域
,操纵数据的过程称为方法
(method
)。对于每个特定的类实例(对象)都有一组特定的实例域值。这些值的集合就是这个对象的当前状态。无论何时,只要想对象发送一个消息,它的状态就有可能发生改变。
实现封装的关键在于绝对不能让类中的方法直接地访问其他类的实例域。程序仅通过对象的方法与对象数据进行交互。
(2)对象
对象的行为:可以对对象施加哪些操作,或者可以对对象施加哪些方法。
对象的状态:当施加那些方法时,对象如何响应。
对象标识:如何辨别具有相同行为与相同状态的不同对象。
同一个类的所有对象实例,由于支持相同的行为而具有家族式的相似性。对象的行为是用可调用的方法定义的。
每个对象都保存着描述当前特征的信息。这就是对象的状态。对象的状态可能会随着时间而发生改变,但这种改变不会是自发的。
对象的状态并不能完全描述一个对象。每个对象都有一个唯一的身份。作为一个类的实例,每个对象的标识永远是不同的,状态常常也存在差异。
(3)类之间的关系
依赖(“uses-a”)
聚合(“has-a”)
继承(“is-a”)
依赖:一个类的方法操纵另一个类的对象,我们就说一个类依赖于另一个类。例如Order类使用Account类是因为Order对象需要访问Account对象查看信用状态。应该尽可能的将相互依赖的类减至最少。如果类A不知道B的存在,它就不会关心B的任何改变(这意味着B的改变不会导致A产生任何bug)。用软件工程的属于来说,就是让类之间的耦合度最低。
聚合:一个Order对象包含一些Item对象。聚合关系意味着类A的对象包含类B的对象。
继承:一般而言类如果类A扩展类B,类A不但包含从B类继承的方法,还会拥有一些额外的功能
很多程序员采用UML
(Unified Modeling Language,统一建模语言)绘制类图,用来描述类之间的关系。
(4)使用预定义类
在Java
中,没有类就没有办法做任何事情,我们前面曾经接触过几个类。然而并不是所有的类都具有面向对象特征。例如:Math
类。在程序中可以使用Math
类的方法,如Math.random
,并只需要知道方法名和参数,而不必了解它的具体实现过程。这正是封装的关键所在,但是Math
类只封装了功能,它不需要也不必隐藏数据。由于没有数据,因此也不必担心生成对象以及初始化实例域。
(5)对象与对象变量
想要使用对象,就必须首先构造对象,并指定其初始状态。然后,对对象应用方法。在Java
程序设计语言中,使用构造器(constructor)
构造新实例。构造器是一种特殊的方法,用来构造并初始化对象。
构造器的名字应该与类名相同。例:Date类的构造器名为Date。想要构造一个Date对象,想要在构造器前面加上new操作符,new Date()
在对象与对象变量之间存在着一个重要的区别。例如:Date deadline;//deadline doesn't refer to any object
定义了一个对象变量deadline,它可以引用Date类型的对象。但是,一定要认识到:变量deadline不是一个对象,实际上也没有引用对象。此时,不能将任何Date方法应用于这个变量上。
一个对象变量并没有实际包含一个对象,而仅仅引用一个对象。
在Java
中,任何对象变量的值都是对存储在另外一个地方的一个对象的引用。new
操作符的返回值也是一个引用。Date deadline = new Date();
有两个部分。表达式
new Date()
构造了一个Date
类型的对象,并且它的值是对新创建对象的引用。这个引用存储在变量deadline
中。可以显式的将对象变量设置为null,标明这个对象变量目前没有引用任何对象。deadline = null; if(deadline != null) System.out.println(deadline);
如果将一个方法应用于一个值为null的对象上,那么就会产生运行时错误。
局部变量不会自动地初始化为null,而必须通过调用new或将它们设置为null进行初始化。
Java
中使用clone
方法获得对象的完整copy
(6)Date
与LocalDate
类
Date
类的实例有一个状态,既特定的时间点
LocalDate
类用来表示大家熟悉的日历表示法,不要使用构造器来构造LocalDate
类的对象。实际上,应当使用静态工厂方法代表你调用构造器:LocalDate.now()
(7)更改器方法和访问器方法
更改器方法:调用某个方法后对象状态改变(比如属性的setter)
访问器方法:只访问对象而不修改对象的方法有时称为访问器方法(比如属性的getter)
(8)用户自定义类
在一个源文件中,只能有一个公有类,但是可以有任意数目的非公有类。
(9)构造器
构造器与类同名,在构造对象时,构造器会运行,以便将实例域初始化为所希望的状态。
构造器与其他的方法有一个重要的不同。构造器总是伴随着new
操作符的执行被调用,而不能对一个已经存在的对象调用构造器来达到重新设置实例域的目的。如果编写一个类时没有编写构造器,那么系统会提供一个无参数构造器。如果类中至少提供了一个构造器,但是没有无参数构造器,则在构造对象时如果没有提供参数就会被视为不合法
1、构造器与类同名
2、每个类可以有一个以上的构造器
3、构造器可以有0、1个或多个参数
4、构造器没有返回值
5、构造器总是伴随着new操作一起调用
如果构造器的第一个语句形如this(...)
,这个构造器将调用同一个类的另一个构造器public Employee(double s) { this("Employee",s); }
(10)隐式参数和显式参数
在instance.method(para)
中,para
是显式参数,instance
对象时隐式参数(有些人把隐式参数称为方法调用的目标或接收者)
(11)基于类的访问权限
一个方法可以访问所属类的所有对象的私有数据class Employee { public booleans equals(Employee other) { return name.equals(other.name); } } if(harry.equals(boos))...
(12)私有方法
对于私有方法,如果改用其他方法实现相应的操作,则不必保留原有方法。只要方法是私有的,类的设计者就可以确信:它不会被外部的其他类操作调用,可以将其删去。如果方法是共有的,就不能将其删去,因为其他的代码很可能依赖它。
(13)final
实例域
可以将实例域定义为final
。构建对象时必须初始化这样的域。也就是说,必须确保在每个构造器执行后,这个域的值被设置,并且在后面的操作中,不能够再对它进行修改。(final
类型的属性,除了在构造器中和声明变量时,无法给属性进行赋值操作)
(14)静态域(类域)
如果将域定义为static
,每个类中只有一个这样的域。而每一个对象对于所有的实例域却都有自己的一份copyclass Employee { private static int nextId = 1; private int id; }
现在每个雇员对象都有一个自己的id域,但这个类的所有实例将共享一个nextId域。换句话说,如果有1000个Employee类的对象,则有1000个实例域id。但是,只有一个静态域nextId。即使没有一个雇员对象,静态域nextId也存在。它属于类,而不属于任何独立的对象。
(15)静态常量
静态变量使用的比较少,但静态常量却使用得比较多。例如,在Math类中定义了一个静态常量:public class Math { public static final double PI = 3.141592653589793; }
在程序中,可以采用
Math.PI
的形式获得这个常量。
(16)静态方法
静态方法是一种不能向对象实施操作的方法。例如:Math
类的pow
方法就是一个静态方法。表达式:Math.pow(x,a)
不使用任何Math
对象。换句话说,没有隐式参数。
静态方法可以访问自身类中的静态域
(17)方法参数
在Java
程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。
(18)重载
有些类有多个构造器。这种特征叫做重载。如果多个方法有相同的名字、不同的参数,便产生了重载。它通过用各个方法给出的参数类型与特定的方法调用所使用的的值类型进行匹配挑选出相应的方法。Java
允许重载任何方法,而不只是构造器方法。因此,要完整的描述一个方法,需要指出方法名以及参数类型。
(19)默认域初始化
如果在构造器中没有显示地给域赋予初值,那么就会被自动地赋为默认值:数值为0、布尔值为false、对象引用为null。
(20)初始化快
在一个类的声明中,可以包含多个代码块。只要构造类的对象,这些块就会被执行。class Employee { private int age; { age = 10; } }
(21)对象析构与
finalize
方法
可以为任何一个类添加finalize
方法。finalize
方法将在垃圾回收器清除对象之前调用。在实际应用中,不要依赖于使用finalize
方法回收任何短缺的资源,这是因为很难知道这个方法什么时候才能够调用;new
究竟做了什么?我们使用new
类构造一个新的类实例时,其实就是告诉JVM
我需要创建一个新的实例。JVM
会开辟一个空间,并调用构造函数来初始化成员变量,最终把引用返回给调用方。
文章:Java堆和栈的区别和介绍以及JVM的堆和栈–https://segmentfault.com/a/1190000014960714
Java学习(三)-对象与类
最新推荐文章于 2023-02-25 11:12:58 发布