面向对象java
对象=属性+服务
操作:函数
封装:把数据和对数据的操作放在一起
对象变量是对象的管理者
VendingMachine v = new VendingMachine()
在函数中可以直接写成员变量的名字来访问成员变量
函数是通过对象来访问的
类定义了对象所具有的变量
this是成员函数的一个特殊的固有的本地变量,它表达了调用这个函数的那个对象
定义在函数内部的变量是本地变量,在函数外部的变量是成员变量
java会给成员变量默认值
构造函数:没有返回类型
对象与类
由类构造对象的过程称为创建类的实例
对象中的数据称为实例域,操纵数据的过程称为方法
对象的行为,标识和状态
类之间的关系:依赖,聚合,继承
在c++中没有空引用,并且引用不能被赋值,可以将java的对象变量看做c++的对象指针
所有java的对象都存储在堆中,当一个对象包含另一个对象变量时,这个变量依然包含着另一个堆对象的指针,在java中,必须使用clone方法获得对象的完整拷贝
更改器方法:对实例域做出修改的方法,访问器方法:仅访问实例域不进行修改
c++(const),java(没有明显区别)
所有java对象都是在堆中构造的,构造器总是伴随new操作符一起使用
隐式参数:出现在方法名前的类对象,显式堆对象:位于方法名后面括号中的数值
设置实例域的值:一个私有的数据域,一个公有的域访问器的方法,一个公有的域更改器方法
如果需要返回一个可变对象的引用,应该首先对它进行克隆,对象克隆是指存放在另一个位置上的对象副本
可以将实例域定义为final,构建对象是必须初始化域,在后面的操作中,不能够再对它进行修改
static:属于类且不属于类对象的变量和函数
值调用:方法接受的是调用者提供的值.引用调用:表示方法接收的是调用者提供的变量地址
方法可以修改传递引用对应的变量值,不能修改传递值所对应的变量值
java总是采用值调用,方法得到的是所有参数值的一个拷贝,方法不能修改传递给它的任何参数变量的内容
一个方法不能修改一个基本数据类型的参数,可以改变一个对象参数的状态,不能实现让对象参数引用一个新的对象
可以通过对象引用拷贝修改所引用的对象状态
public static void tripleValue(double x)
{
x = 3 + x;
System.out.println("end of salary="+x);
}
public static void tripleSalary(Employee x)
{
x.raiseSalary(200);
System.out.println("end of salary="+x.getSalary());
}
public static void main(String[] args)
{
System.out.println("testing triple:");
double percent = 10;
System.out.println("before:percent="+percent);
tripleValue(percent);
System.out.println("after:percent="+percent);
System.out.println("\ntesting triple:");
Employee harry = new Employee("Harry", 50000);
System.out.println("before:percent="+harry.getSalary());
tripleSalary(harry);
System.out.println("after:percent="+harry.getSalary());
}
class Employee
{
public Employee(String n,double s)
{
name = n;
salary = s;
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
private String name;
private double salary;
}
testing triple:
before:percent=10.0
end of salary=13.0
after:percent=10.0
testing triple:
before:percent=50000.0
end of salary=150000.0
after:percent=150000.0
如果多个方法有相同的名字,不同的参数,便产生了重载
重载解析:根据方法给出的参数类型和特定方法调用所使用的值的类型进行匹配挑选相应的方法
可以重载任何方法
构造器不明确的对域初始化,会影响代码的可读性,会自动赋为默认值
默认构造器
可以调用方法对域进行初始化
static int assignId()
{
int r = nextId;
nextId++;
return r;
}
private static int nextId;
private int id = assignId();
this:引用方法的隐式参数,this()构造器将调用同一个类的另一个构造器
在一个类的声明中,可以包含多个代码块,只要构造类的对象,这些块就会被执行
public Employee(double s)
{
this("Employee #" + nextId,s);
nextId++;
}
调用构造器的具体处理步骤:1.所有数据域被初始化为默认值,2.按照在类声明中出现的次序,依次执行所有域初始化语句和初始化块3.按照构造器第一行调用了构造器,则执行第二个构造器 4.执行这个构造器的主体
静态初始化块
public class hello
{
static
{
System.out.println("hello world");
}
}
初始化块
class Employee
{
private static int nextId;
{
id = nextId;
nextId++;
}
}
无论使用哪个构造器构造对象,id域都在对象初始化块中被初始化,先运行初始化块,再运行构造器的主体部分
如果对类的静态域进行初始化的代码比较复杂,可以使用静态的初始化块
static
{
Random generator = new Random();
nextId = generator.nextId(1000);
}
java不支持析构器,有自动的垃圾回收器
只要将类放置在不同的包中,就不会产生类的冲突
import语句不仅可以导入类,还可以导入静态方法和静态域
import static java.lang.System;
out.println("hello");
exit(0);
将一个类放入包中,必须将包的名字放在源文件的开头,包中定义类的代码之前
package com.horstmann.corejava;
public class Employee
{
}
com/horstmann/corejava/Employee.class
如果没有指定public或private,标记为public的部分可以被同一个包中的所有方法访问
文档注释
javadoc,可以由源文件生成一个HTML文档
javadoc从几个特性中抽取信息:包,公有类和接口,公有的和受保护的方法,公有的和受保护的域
注释以/**开始,以*/结束,标记后面紧跟这自由格式文本,标记由@开始
类注释在import语句后,类定义前
方法注释:放阿紫所描述的方法之前
域注释:公有域
通用注释
包与概述注释:在每一个包目录中添加一个单独的文件
类设计
一定将数据设置为私有(不要破快封装性),一定要对数据初始化,不要在类中过多使用基本数据类型(用其他的类代替多个相关的基本数据类型的使用),不是所有域都需要独立的域访问器和更改器,使用标准格式进行类的定义(公有访问特性部分,包作用域访问特性,私有访问特性)每个部分(实例方法,静态方法,实例域,静态域),将职责过多的类进行分解,类名和方法名要体现它们的职责.