运用数据抽象的思想编写代码(定义和使用数据类型,将数据类型的值封装在对象中)的方式称为面向对象编程。
数据类型指的是一组值和一组对值的操作的集合。对象是能够存储任意该数据类型的值的实体,或数据类型的实例。
对象的三个主要特性
行为:可以对对象完成哪些操作,或者可以对对象应用哪些方法。同一个类的所有对象实例,由于支持相同的行为而具有家族式的相似性。
状态:描述当前状况的信息。对象状态的改变必须通过调用方法实现。
标识:每个对象都有一个唯一的标识,用于区分具有相同行为与状态的不同对象(比如在订单系统中,即使两个订单货物完全相同,那也是不同的订单)。
类之间的关系
依赖(uses-a):如果一个类的方法使用或操纵另一个类的对象,我们就说一个类依赖于另一个类。应该尽可能地将相互依赖的类减至最少。
聚合(has-a):类A的对象包含类B的对象。
继承(is-a):如果类A继承类B,那么类A不但包含从类B继承的方法,还会有一些额外功能。(比如有一个RushOrder类,继承自Order类,包含了一些用于优先处理的特殊方法,而其他的一般性方法都继承自Order类)
包
包的作用
1. 区分相同名字的类,可以在不同的包中定义相同名字的类。
2. 当类很多时,可以很好的管理类(类似Java API文档)。
3. 控制访问范围。
基本语法
package com.hspedu; 其中package为关键字,表示引入包。com.hespedu表示包名。
本质分析
包实际上就是创建不同的文件夹来保存类文件。
创建一个包:
com.xiaoming,其中这个 '.' 表示分级,com为一级目录,xiaoming为二级目录。
举例:
import com.shang.Person;
public class HelloWorld {
public static void main(String[] args) {
Person a = new Person(); //导入的可以直接使用
com.xiaoming.Person b = new com.xiaoming.Person(); //没有导入就要写全名字
a.showName();
b.showName();
}
}
去除 import后自动隐藏
把 "Optimize imports on the fly" 取消即可。
命名
命名规则:
只能包含数字、字母、下划线、小圆点,但不能用数字开头,不能是关键字或保留字。
命名规范:
com.公司名.项目名.业务模块名,全部用小写字母。
com.sina.crm.uese; //用户模块
com.sina.crm.order; //订单模块
com.sina.crm.utils; //工具类
常用包
包的使用细节
1. package语句的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多只有一句package。
2. import指令放在package的下面,在类定义前面,可以有多句并且没有顺序要求。我们用 import 引入包,主要是为了使用包中的类。不建议使用 * 引入全部的类。
访问修饰符
访问范围
注意子类说的是不同包里的子类,同一个包里的子类是可以访问父类的默认属性的。
public class A{
protected String name = "ss";
String age = "18";
}
//在不同包
public class B extends A{
public static void main(String[] args){
B b = new B();
//可以访问 name, 但是不可以访问 age
}
}
注意事项
1. 修饰符可以用来修饰类中的 属性,成员方法以及类。成员方法与属性都符合上图的范围。
2. 只有默认和public才能修饰类,默认类只有在同一个包中才能调用,在不同包中,即使使用了import导入该类,也不能用。而public修饰的类不仅在本包中可以调用,也可以在不同包中进行调用,但是需要import导入类。
按值调用与按引用调用
按值调用表示方法接收的是调用者提供的值。按引用调用表示方法接收的是调用者提供的变量地址。 方法可以修改按引用传递变量的值,而不能修改按值传递变量的值(其实就是C++的形参与实参的关系,引用就是加上了&)。
按值调用举例:假如在Employee类中加入一个方法——
public void add(int x) {
x += 10;
}
然后在主函数中调用,分析一下过程:1.x初始化为num的一个副本(形参,也就是10) 2.x加上10后等于20,但是num仍为10。 3.方法结束后,参数变量x不再使用。
public static void main(String[] args) {
int num = 10;
Employee a = new Employee(10);
System.out.println("调用add函数前为:"+num);
a.add(10);//这个就是按值调用
System.out.print("调用add函数后为:"+num);
}
按引用调用举例:给Employee类增加另外一个方法,这时传入一个类。
public void add(Employee one) {
one.id += 10;
}
在主函数进行调用——1.one初始化为a的一个副本,这里就是一个对象引用。 2.add方法应用于这个对象引用。one和a同时引用一个Employee对象。 3.方法结束后,参数变量one不再使用,但是a做出了修改。
public static void main(String[] args) {
Employee a = new Employee(10);
System.out.print("调用add函数前——");
a.showId();
a.add(a);
System.out.print("调用add函数后——");
a.showId();
}
但是要注意一点,Java对对象采用的并不是引用调用,而是按值传递的。
public static void swap(Employee x,Employee y)
{
Employee temp = x;
x = y;//这个就触犯了 不能让一个对象参数引用一个新的对象
y = temp;
}
实际上并不能交换传入的对象。 总结一下Java中对方法参数能做什么和不能做什么——1.方法不能修改基本数据类型(数值型,布尔型等)。 2.方法可以改变对象参数的状态(传入一个类修改该类的各项数值)。 3.方法不能让一个对象参数引用一个新的对象。(比如交换两个对象)
类的设计技巧
1.一定要保证数据私有。2.一定要对数据进行初始化(最好不要依赖于系统的默认值)。 3.不要在类中使用过多的基本类型。 4.不是所有的字段都需要单独的字段访问器和字段更改器。5.分解有过多职责的类。 6.类名和方法名要能够体现它们的职责。 7.优先使用不可变的类。