-
以后开篇写5个成功故事,
8:30 弹吉他
9:20开始写csdn博客
吃饭没看手机
勇敢说出:不要用过去定义未来的我
Java看到700页鼓励自己:
- 是否可以用移位来实现各位之和呢?:查完发现好像只有二进制才有移位这一说
- 昨晚学习了别的同学的思路,优化了之前那个找9倍数的题,连续的事情离散的看,离散的事情连续的看。
封装
将对象的Field(成员变量,static修饰的)和实现细节隐藏起来,不允许外部直接访问。把方法暴露出来,让方法来控制对这些Field进行安全的访问和操作。
访问控制符
private(当前类访问权限):如果类里的一个成员(包括Field、方法和构造器等)使用private访问控制符来修饰,则这个成员只能在当前类的内部被访问。很显然,这个访问控制符用于修饰Field最合适,使用它来修饰Field就可以把Field隐藏在该类的内部。
default(包访问权限):如果类里的一个成员(包括Field、方法和构造器等)或者一个外部类不使用任何访问控制符修饰,我们就称它是包访问权限,default访问控制的成员或外部类可以被相同包下的其他类访问。关于包的介绍请看5.4.3节。
protected(子类访问权限):如果一个成员(包括Field、方法和构造器等)使用protected访问控制符修饰,那么这个成员既可以被同一个包中的其他类访问,也可以被不同包中的子类访问。在通常情况下,如果使用protected来修饰一个方法,通常是希望其子类来重写这个方法。关于父类、子类的介绍请参考5.6节的内容。
public(公共访问权限):这是一个最宽松的访问控制级别,如果一个成员(包括Field、方法和构造器等)或者一个外部类使用public访问控制符修饰,那么这个成员或外部类就可以被所有类访问,不管访问类和被访问类是否处于同一个包中,是否具有父子继承关系。
如果一个Java源文件里定义的所有类都没有使用public修饰,则这个Java源文件的文件名可以是一切合法的文件名;但如果一个Java源文件里定义了一个public修饰的类,则这个源文件的文件名必须与public修饰的类的类名相同。
对于访问控制符的使用,存在如下几条基本原则。[插图] 类里的绝大部分Field都应该使用private修饰,只有一些static修饰的、类似全局变量的Field,才可能考虑使用public修饰。除此之外,有些方法只是用于辅助实现该类的其他方法,这些方法被称为工具方法,工具方法也应该使用private修饰。[插图] 如果某个类主要用做其他类的父类,该类里包含的大部分方法可能仅希望被其子类重写,而不想被外界直接调用,则应该使用protected修饰这些方法。[插图] 希望暴露出来给其他类自由调用的方法应该使用public修饰。因此,类的构造器通过使用public修饰,从而允许在其他地方创建该类的实例。因为外部类通常都希望被其他类自由使用,所以大部分外部类都使用public修饰。
package、import
初学者以为只要把生成的class文件放在某个目录下,这个目录名就成了这个类的包名。这是一个错误的看法,不是有了目录结构,就等于有了包名。为Java类添加包必须在Java源文件中通过package语句指定,单靠目录名是没法指定的。Java的包机制需要两个方面保证:① 源文件里使用package语句指定包名;② class文件必须放在对应的路径下。
**Java语法只要求包名是有效的标识符即可,但从可读性规范角度来看,包名应该全部是小写字母,而且应该由一个或多个有意义的单词连缀而成。在实际企业开发中,我们还会在org.crazyit包下以项目名建立子包;如果该项目足够大,则还会在项目名子包下以模块名来建立模块子包;如果该模块下还包括多种类型的组件,则还会建立对应的子包。假设有一个eLearning系统,对于该系统下学生模块的DAO组件,则通常会放在org.crazyit.elearning.student.dao包下,其中elearning是项目名,student是模块名,dao用于组织一类组件。
package语句必须作为源文件的第一条非注释性语句,一个源文件只能指定一个包,即只能包含一条package语句,该源文件中可以定义多个类,则这些类将全部位于该包下。**
this
java提供了一个this关键字,this关键字总是指向调用该方法的对象。根据this出现位置的不同, this作为对象的默认引用有两种情形:
构造器中引用该构造器正在初始化的对象;
在方法中引用调用该方法的对象。
**this关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或Field。**假设定义了一个Dog类,这个Dog对象的run方法需要调用它的jump方法,那么应该如何做?是否应该定义如下的Dog类呢?
public class Dog
{
//定义一个jump方法
public void jump()
{
System.out.println("正在执行jump方法");
}
//定义一个run方法,run方法需要借助jump方法
public void run()
{
Dog d=new Dog();
d.jump();
System.out.println("正在执行run方法");
}
}
public class Dog
{
//定义一个jump方法
public void jump()
{
System.out.println("正在执行jump方法");
}
//定义一个run方法,run方法需要借助jump方法
public void run()
{
//使用this引用调用run()方法的对象
this.jump();
System.out.println("正在执行run方法");
}
}
现在我们建了一个类A,然后这个类有多个方法和成员变量,我们在方法1中调用方法2,不需要再把A实例化,再通过A来调用方法2,而是直接this.方法2
编程时不要使用对象去调用static修饰的Field、方法,而是应该使用类去调用static修饰的Field、方法!如果在其他Java代码中看到对象调用static修饰的Field、方法的情形,完全可以把这种用法当成假象,将其替换成用类来调用static修饰的Field、方法的代码。
方法
- 方法必须存在在类体里
- 传参一般是值传递,方法中对参数的改变,不影响原值。这个参数是建立的副本栈区的值,原来的栈区不改变。
- 引用传递:参数是 A a,相当于传递的是引用变量,也就是指针,所以会导致原值改变。
- 方法重载的要求就是两同一不同:同一个类中方法名相同,参数列表不同。至于方法的其他部分,如方法返回值类型、修饰符等,与方法重载没有任何关系。
- 提问:为什么方法的返回值类型不能用于区分重载的方法?
答:对于int f(){}和void f(){}两个方法,如果这样调用int result=f();,系统可以识别是调用返回值类型为int的方法;但Java调用方法时可以忽略方法返回值,如果采用如下方法来调用f();,你能判断是调用哪个方法吗?如果你尚且不能判断,那么Java系统也会糊涂。在**编程过程中有一条重要规则:不要让系统糊涂,系统一糊涂,肯定就是你错了。**因此,Java里不能使用方法返回值类型作为区分方法重载的依据。
6.
[插图] 如果需要定义的变量是用于描述某个类或某个对象的固有信息的,例如人的身高、体重等信息,它们是人对象的固有信息,每个人对象都具有这些信息。这种变量应该定义为成员变量。如果这种信息对这个类的所有实例完全相同,或者说它是类相关的,例如人类的眼睛数量这个Field,目前所有人的眼睛数量都是2,如果人类进化了,变成了3个眼睛,则所有人的眼睛数量都是3,这种类相关的信息应该定义成类Field;如果这种信息是实例相关的,例如人的身高、体重等,每个人实例的身高、体重可能互不相同,这种信息是实例相关的,因此应该定义成实例Field。[插图] 如果在某个类中需要以一个变量来保存该类或者实例运行时的状态信息,例如上面五子棋程序中的棋盘数组,它用以保存五子棋实例运行时的状态信息。这种用于保存某个类或某个实例状态信息的变量通常应该使用成员变量。[插图] 如果某个信息需要在某个类的多个方法之间进行共享,则这个信息应该使用成员变量来保存。例如,在把浮点数转换为人民币读法字符串的程序中,数字的大写字符和单位字符等是多个方法的共享信息,因此应设置为成员变量。