您的位置:首页 > 编程语言 > Java开发

Java 7:类和对象(域、参数、初始化)

2017-03-02 17:23 120 查看
面向对象编程:每个对象包含对用户公开的特定功能部分和隐藏的实现部分,在OOP中不必关心对象的具体实现,OOP更看重数据(结构),而不是具体算法。

封装(数据隐藏):将数据和行为组合在一个包里,并对对象的使用者隐藏数据的实现方式,封装的关键是绝不能让其他类直接访问实例域,仅通过方法来交互(提高重用性和可靠性的关键)

对象中的数据成为“实例域”(instance field),操作数据的过程称为“方法”(method),所有实例域的集合就表示了这个对象的当前状态。

传统的过程化程序设计,必须从顶部的main函数开始编写程序,OOP中没有所谓的顶部,先从设计类开始,再往类中添加方法。

Date d;定义了一个对象变量,不是一个对象,没有初始化的变量调用方法会报编译错误。如果给一个null则报空指针错误(运行时错误)

对象变量的值是“对存储在另一个地方的对象的引用”

局部变量不会自动初始化为null,必须通过new或者手动设置为null进行初始化



在一个原文件只能有一个公有类,名字必须与类名相同,但是可以有多个非公有类。

不要编写返回引用可变对象的访问器方法,会破坏封装性。 如果需要返回可变对象的引用,首先需要对其进行克隆



private int i;
public Employee(int i){
this.i=i;
}
public void gt(Employee a){
System.out.println(a.i);
}
方法可以访问调用它的对象的私有数据,不能访问其他类的私有域,但是这里,this和Employee a是同一个类的对象,即使i是private,也可以访问

final 实例域

必须保证每一个构造器之行之后,fianl域被设置,后续操作不能修改它的值。

要么:private final int i=1;直接赋值

要么:在构造函数中赋值

final一般修饰基本类型域、不可变类型域,如果类中的每个方法都不会改变其对象,就是不可变的类,

fianl修饰可变类型域,可能会引起混乱,例如引用一个Date,对象引用不能改变,但是对象本身可以用Date内部的方法改变

static静态域

每一个对象对于所有的实例域都有自己的一份拷贝,但是对于静态域,一个类只有一份,即使没有类对象,静态域也存在

静态常量:比如Math类中的public static final double Pi=3.14。。。。

静态方法:

静态方法是不能向对象实施操作的方法,没有隐式参数this,例如Math.pow(x,a)

静态方法可以访问静态域,也可以传一个类对象作为参数,来访问参数对象

什么时候使用静态方法:

1、一个方法不需要访问对象状态,其所需参数都是通过显式参数提供(比如Math.pow())

2、方法只需要访问类的静态域

参数传递:

按值调用:方法接收的是值(的拷贝,不能修改)Java采取按值调用,不必理睬方法收到参数以后的具体操作,不会对参数变量造成影响

按引用调用:方法接收调用者提供的变量地址(可以修改变量值)

方法参数的两种类型:1、基本数据类型
2、对象引用

一个方法不可能修改一个基本数据类型的参数,

一个对象引用可以修改对象内部状态,但是不能让对象参数引用一个新对象

方法重载:通过签名(包括方法名+参数类型+参数个数,不包括返回值)来选择重载函数

默认域初始化:如果构造器没有显式地赋予初值,那么数值自动为0,boolean值自动为false,对象引用自动为null;

Java编程思想说磨默认的构造函数会给所有的实例域赋初值,然而发现,在构造函数执行完之前,所有的实例域就已经有了默认初值。

如果修改了构造函数,没有默认的无参构造函数,也是一样的,实例域的初值赋予是在构造函数之前的,与构造函数没有直接关系。

仅当类没有提供任何构造函数的时候,系统才会提供一个默认构造函数。

可以在类定义时直接赋值:

private String name=“12”;
初始值不一定是常量,也可以调用方法来初始化。
public int iii=returni();
public int returni(){
return 33;
}


构造函数调用this(....)另一个构造函数,但是调用别的构造函数必须放在第一句话

初始化块:

首先运行初始化块,然后才是构造函数。

{
i=2;
System.out.println(i);//Wrong!
}
public int i=1;
这里可以对i进行赋值,但是不能在声明之前操作它,如果i是Date,可以操作i=。。。,但是也是不能输出和调用相关函数

{
i=2;
}

{
i=3;
}
public Employee(){
System.out.println("i="+i);
}
public int i=1;
构造函数输出i=1,
{
i=2;
}
public int i=1;
{
System.out.println(i);
i=3;
}

这样就可以输出i等于1,最终构造函数时i=3

public int i;
{
System.out.println(i);输出0
i=2;
}

{
System.out.println(i);
i=3;
}

这个“bug“,在《核心技术》里提到,“即使在类的后面定义,仍然可以在初始化块中设置域。但是为了避免循环定义,不要读取在后面初始化的域,该规则很复杂。。。。”

建议将初始化块放到类定义之后。

步骤:

1、所有数据初始化为默认值(0,false,null)

2、按照类声明中出现次序,依次执行所有初始化语句和初始化块

3、如果构造器第一行调用了第二个构造器,则执行第二个构造器主体

4、执行这个构造器主体

对于静态域的初始化,声明的时候赋予值或者使用静态初始化块。

静态初始化块会在所有初始化块之前执行,但是只在类第一次加载时执行一次。普通初始化块每次生成类对象都要执行一次。

仅仅声明一个类的变量而不进行new,不会调用任何初始化块(也没有执行构造函数)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 语言