java基础

[b]对象和对象变量[/b]
1:如Date deadline;它定义了一个Date对象的变量deadline,此变量可以引用Date类型的变量,但是一定要认识到deadline不是一个对象,实际上也没有引用对象,此时不能将任何Date的方法应用于这个变量上。如deadline.toString()就会产生编译错误。
2:如果要对对象变量进行操作就必须初始化对象变量,初始化有两种情况,一是创建对象,deadline = new Date(),另一种是引用一个已经存在的对象Date birthday = new Date();deadline = birthday;
3:初始化之后的对象变量其实并没有实际包含一个对象,而仅仅是引用了一个对象,在java中,任何对象变量的值都是都是对存储在另外一个地方的一个对象的引用,new操作符的返回值也是一个引用,如Date deadline = new Date();这个语句分为两部分,表达式new Date()构造了一个Date类型的对象,并且它的值是对新创对象的一个引用,这个引用存储在变量deadline中。
4:其实可以显示的将对象变量设置为null,表明这个对象变量没有引用任何对象,如果一个方法应用于一个值为null的对象上,就会产生运行时错误,变量不会自动初始化为null,而必须通过new或者将他们设置为null进行初始化。
5:例如Date deadline;deadline.toString()会产生编译时错误,应为没有初始化,[b]这一点说明对象变量没有自动的被初始化默认值为null[/b];然后Date deadline = null;deadline.toString()不会编译错误,但是会产生运行时错误,因为产生了[b]空指针异常[/b]。
[b]时间和日历[/b]
java中用Date来表示时间(即时间点),而用GregorianCalendar来表示日历,将时间和日历分开是一种很好的面向对象的设计,Date类只提供了少量的用来比较的两个时间点,如before,after等方法,还有其他的getDay()等,但是不建议使用。GregorianCalendar类包含的方法比Date要多得多,特别是提供了几个有用的构造方法,如:new GregorianCalendar()表示当前的时间,new GregorianCalendar(1999,11,31),这里请注意月份是从0开始的,所以月份一般用常量的方式表现,如new GregorianCalendar(1999,Calendar.December,31,23,59,59).对于GregorianCalendar类型的日历包括了很多的信息,如果只需要简单的想Date一样的信息可以getTime()就行了,如果要得到具体的年月日等信息可以GregorianCalendar now = new GregorianCalendar();int year = now.get(Calendar,YEAR);相应的要改变就now.set(Calendar.YEAR,2012);[b]Date和Calendar之间的转换[/b]:
GregorianCalendar calendar = new calendar(year,month,day);Date time= calendar.getTime();Calendar.setTime(time)
[b]java自定义类[/b]
在一个java源文件中,源文件名必须和public类的类名一致,在一个java源文件中可以有很多的类,但是只能一个public的类,在每个类里面都可以有main入口函数,但是在运行程序的时候一次只能选择一个入口函数。
但是一般的情况程序员喜欢每一个类一个源文件编写,而且在编译的过程中,如果在编译一个源文件的时候碰到其他的类,java虚拟机会在当前位置下面找到相应的class文件,如果没有,就会找到相应的java源文件,并且对他进行编译。
一个类的实例域我们建议用private,而不是public,public会然其他类有任意修改的权限,破坏了安全性和封装性,private的情况下,我们可以向外提供操作的接口。
构造器总是随着new操作符的执行被调用,而不能对已近存在的对象调用构造方法达到重新设置实例域的目的,如Employee employee = new Employee();employee.Employee(),这样会报编译错误。构造器有如下特点:
1>构造器名和类名相同
2>每个类可以有一个以上的构造器
3>构造器可以有任意个参数
4>构造器没有返回值
5>构造器总是伴随着new操作一起调用的
不要在构造器中定义与实例域重名的局部变量,这些变量只能在构造器内部访问,这些变量屏蔽了同名的实例域,例如:public Employee(double s){double salary = s;}这样就不会设置类的实例域,因为被屏蔽了。操作的局部的,而不是全局的那个。
java方法中的显示参数是指方法中传进去的参数,隐式参数是指用this调用的参数。
[b]注意[/b]:不要编写返回引用可变对象的访问器方法,如:
class Employee{
private Date hireDay;
public Date getHireDay(){return hireDay;}
}
在这种情况下会破坏类的封装,如下:
Employee harry = ....;
Date d = harry.getHireDay();
d.setTime(...);
所以如果需要返回一个可变对象的引用,应该首先对他进行克隆,如:
class Employee{
public Date getHireDay(){
return (Date)hireDay.clone();
}
}
[b]final实例域[/b]
final实例域必须在构建对象的时候进行设置或者叫初始化,在后面的操作中不能再对他进行修改,但是final修饰的一般是基本数据类型或者是不可变类的域,如private final String name = "wjj",如果是可变的类可能会对读者造成混乱,如privat final Date hireDay,像这种情况,不变的是、引用,但是不能保证引用的数据不变化。
[b]static静态域[/b]
static静态域是指全类所有,每一个实例中的次域只是类静态域的一个拷贝,所以当一处改变,其他地方也会改变。
[b]域和局部变量的区别[/b]:局部变量必须在方法中明确的初始化,但是域变量如果没有初始化,他会赋予默认的初始值
[b]静态常量[/b]:public static final xxx = xxx;

[b]静态方法[/b]
静态方法是一种不能向对象实施操作的方法,即没有隐式(this)的参数,正因为这样,所以不能在静态方法中访问实例域。只能访问里面的实例域。虽然除了用类名直接调用外,还可以用类的引用来调用静态方法,但是这样会造成混乱,不建议这样做。
静态方法还有一个用途就是factory方法,出现这种的原因可能有1:无法命名构造方法,应为需要产生几种不同风格的对象,2:当使用构造器时,不能改变所构造的对象类型,如需要操作的是自己类的子类的情况。
[b]方法参数[/b]
值调用:表示方法接受的调用者提供的值,引用调用表示方法接受的调用者提供的变量地址,一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值------[b]java程序语言总是采用值传递[/b],也就是说,方法得到的是所有参数值的一个拷贝,特别地,方法不能改变传递给他的任意参数变量的内容。由于方法参数有两种类型,一种是基本数据类型,另一种是对象的引用,在对象引用的情况下,拷贝的引用,但是对引用的操作也会影响到原数据,有些人就认为是引用传递,但是我们看一下交换两个雇员对象的方法就可以清楚,其实java方法并没有交换掉两个雇员的元数据,交换的知识引用的copy。现在对java方法调用总结如下:
1>一个方法不能修改一个基本数据类型的参数
2>一个方法可以改变一个对象参数的状态
3>一个方法不能实现对对象参数引用一个新的对象
[b]继承[/b]
继承就是复用被继承类的属性和方法,子类和父类之间是典型的"is-a"关系。例如:manager和employee之间的关系就是典型的"is-a"关系。在这里父类并没有比子类多很多属性和功能,恰恰相反,子类一般比父类多很多属性和方法,这里可以这么理解,祖先都是很简单的,后来的人类发展了很多人类的特有方法,但是他还是保存着祖先的最基本的特征。
在子类中可以增加域,增加方法或者覆盖超类的方法,然而决不能删除继承的任何域和方法;在java中,所有的继承都是公有继承,意思就是子类默认拥有父类的公有属性和方法,虽然这些方法或者属性没有显示的编写,但是其他类可以通过子类调用这些父类的方法。而对于私有的属性,在子类外部也是通过子类的构造方法(super(...))或者从父类默认继承过来的get和set方法来设置。而私有的方法就没有办法了,只有类本身可以调用。而出现父类和子类同名的函数时,我们通过super来区分,而这里的super不是对象的一个引用,不能将super赋给一个对象变量,它只是一个指示编译器调用超类方法的特有关键字。
这里区分一些[b]super[/b]和[b]this[/b]:关键字this有两个用途,一是引用隐式参数,而是调用该类的其他构造方法,同样super也有两个用途,一是调用超类的方法,而是调用超类的构造器。
多态:一个对象变量可以引用多种实际类型的现象,如:
Employee[] staff = new Employee[2];
staff[0] = new Manager(...);
staff[1] = new Employee(...);
动态绑定:在运行时能够自动的选择调用哪个方法的现象。如:
for(Employee e:staff){
System.out.println(e.getName()+" "+e.getSalary());
}
[b]阻止继承[/b]:有时候可能希望阻止人们利用某个类定义子类,不允许扩展的类称为final类,并且用final修饰,其实类中的方法也可以被申明为final,如果这样,子类不能覆盖这个方法,final类中的所有方法自动成为final方法,而不包括域。
[b]带有继承关系的类的初始化顺序[/b]:
1.父类--静态变量
2.父类--静态初始化块
3.子类--静态变量
4.子类--静态初始化块
5.父类--变量
6.父类--初始化块
7.父类--构造函数
8.子类--变量
9.子类--初始化块
10.子类--构造函数
注意: 静态的总是先于非静态的
但是同为静态的或者非静态的变量和块之间的先后顺序是 谁先定义就谁先执行的
[b]单个类的初始化顺序[/b]:
1. 静态变量
2. 静态初始化块
3. 变量
4. 初始化块
5. 构造函数
记着,最后调用的才是构造函数
下面归纳一下java用于控制可见性的4个访问修饰符:
1)private ----仅对本类可见
2)public -----对所有类可见
3)protected -----对本包和所有子类可见
4)默认对本包可见
[b]完美equals方法建议[/b]:
1)显式参数名称为otherObject,稍后需要将它转换成应外一个叫other的变量。
2)检测this于otherObject是否引用同一个对象
if(this==otherObject)return true;
3)检测otherObject是否为null,如果为null,返回为false,这项检测是很必须的
if(otherObject==null)return false;
4)比较this于otherObject是否属于同一个类,如果equals的语意在每个子类中有所改变,就使用getClass检测
if(getClass!=otherObject.getClass())return false;
5)如果所有的子类都拥有统一的语义,就用instanceof检测;
if(otherObject instanceog(ClassName))return false;
6)将otherObject转换为相应的类类型变量
ClassName other = (ClassName)otherObject
7)最后就就开始对所需进行所需的域进行比较就是了,使用==比较基本类型域,使用equals比较对象域。
return filed1==other.filed1 $$filed2.equals(other.filed2)&&...;
8)如果在子类中重新定义equals,就要在其中包含调用super.equals(other);
9)[b]注意[/b]在覆盖父类方法时候由于父类的参数是object,而在覆盖的时候往往是显式的传参,所以不是覆盖而是重新写了一个无关的equals方法。
[b]hashcode[/b]
equals于hashCode的定义必须一致,也就是说如果x.equals(y)返回true,那么x.hashCode()喝y.hashCode()具有相同的值。两个相等的对象要求返回相等的散列表。
[b]toString方法[/b]
随处可见toString()方法的主要原因是:只要对象与一个字符串通过操作符“+”连接起来,java编译就会自动的调用toString()方法,以便获得这个对象的字符串描述。
而对于数组:由于数组继承了object类的toString方法,如
int[] luckNumber = {1,3,4,6};
String s = ""+luckNumber;
生成字符串[I@1a46e30,而修正的方法是调用静态方法Array.toString();代码如下:
String s = Array.toString(luckNumbers);将生成字符串"[1,3,4,6]"
对于多维数组则需要调用Arrays.deepToString()方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值