java简单数据操作
java支持double类型取模
double a = 5.6;
double b = 11.8;
double c = b % a;
System.out.println(c);
输出 0.6
java支持double类型自加自减
double a = 1.5;
a++;
System.out.println(a);
输出2.5
比较运算符 != 和==
两个引用之间的比较,比较的是指向的是不是同一个对象,而不是比较所指对象的信息是否相同。
java中没有无符号数,char型为两个字节
移位运算符 >> << >>>
“<<” 左移,低位补0
“>>” 右移,高位补这个数的符号(正数补0,负数补1)
“>>>” 右移,高位补0
java中有boolean布尔类型,占一位,true or false
默认初始化为false
java 里面没有“非0就是true”这种规则!
java中的变量类型
public class example{
static int a = 5; //类变量,和类一起加载,可以用类名直接调用,默认初始化是0
int b; //实例变量。需要该类new一个instance实例后,用该实例调用,自动初始化为0,或按构造方法初始化
static{ //静态代码块,在加载类时执行,因此在main函数执行之前执行
System.out.println("123"); //在输出a的值之前输出
}
public static void main(String[] args){
int c; //初始化以后才能使用
System.out.println(a); //5
System.out.println(b); //报错,需要实例调用
System.out.println(c); //报错,未初始化
}
}
继承与接口
1.继承为单继承关系,不能有多个父类
2.接口为多继承关系,一个类可以实现多个接口
3.接口本身只能用extends来继承多个接口,但不能implements这些接口。
规则
子类可以继承父类除了private和final修饰的所有方法和属性,当子类要调用父类的方法或属性时,直接由super关键字。
子类实现某个接口时,要实现接口中的所有抽象方法,不然,子类本身就会变成一个抽象类。
抽象类
抽象类只是一个有抽象方法的特殊的类,基本特征与普通类相同,抽象类不能new实例,必须实现了所有的抽象方法才可以
public class AbstractExtends{
public static void main(String[] args){
BaseUser baseUser = new BaseUser() {//抽象类要重写了所有抽象方法才能new实例
@Override
public void helloFirstAbstract(){
System.out.println("hello baseUser.helloFirstAbstract()");
}
@Override
public void helloSecondAbstract(){
System.out.println("hello baseUser.helloSecondAbstract()");
}
};
baseUser.hello(); //调用抽象类定义的具体的方法
baseUser.helloFirstAbstract(); //调用上面实现的方法
baseUser.helloSecondAbstract();
System.out.println("----------------");
UserOne userOne = new UserOne() {
@Override
public void helloSecondAbstract() {
System.out.println("hello userOne.helloSecondAbstract()");
}
};
userOne.hello(); //调用继承自抽象类的一个具体方法
userOne.helloFirstAbstract();
userOne.helloSecondAbstract();
System.out.println("----------------");
UserTwo userTwo = new UserTwo(); //这个类实现了继承的抽象类的所有抽象方法,是一个具体类
userTwo.hello();
userTwo.helloFirstAbstract();
userTwo.helloSecondAbstract();
}
}
abstract class BaseUser{
public void hello(){
System.out.println("hello BaseUser.hello()");
}
public abstract void helloFirstAbstract();
public abstract void helloSecondAbstract();
}
abstract class UserOne extends BaseUser{
public void helloFirstAbstract(){
System.out.println("hello UserOne.helloFirstAbstract()");
}
}
class UserTwo extends UserOne{
public void helloFirstAbstract(){
System.out.println("hello UserTwo.helloFirstAbstract()");
}
public void helloSecondAbstract(){
System.out.println("hello UserTwo.helloSecondAbstract()");
}
}
接口interface
抽象类与接口的区别
1. 抽象类可以有具体的方法,接口里面所有的方法都是抽象的
2. 接口没有构造函数,没有this,super关键字,而抽象类和普通类类似,有一个系统默认的无参构造函数,有this和super,方面子类继承时实现自己的构造函数
3. 接口的成员变量是常量,用public static final修饰,接口的成员函数都用public abstract修饰
final关键字
- 修饰普通变量时,表示该变量以后不能被赋值
- 修饰方法时,表示该方法不能被继承,如果没有用private修饰,那么子类仍然可以调用该方法
- 修饰类时,表示该类不能被继承
- 修饰引用时,表示该引用不能再指向别的对象了,并不表示不能修改所指的对象,即,该引用是一个常量,但引用指向的对象并不是常量
重载和重写 overload,overriding
- 重载的时候,只能通过不同的参数表(不包括该函数的访问权限,返回值,抛出的异常),根据参数表的个数、类型、顺序的不同
- 重写的时候,重写方法的所有签名都必须相同(包括参数表,返回值)
对象的拷贝
如下代码:
Object a = new Object();
b = a
实际上a和b只想相同的一块内存区域,因此,当修改a时也会修改b的值,有时,这并不是我们所希望看到的,我们希望能分配两块内存区域,让ab只想两个对象,而这两个对象有相同的值
public class Clone {
public static void main(String[] args){
AClass class1 = new AClass();
class1.a = 12;
AClass class2 = (AClass)class1.clone();//class1的clone调用了他的父类Object的clone函数,将内容在内存中复制了一份,交给class2
System.out.println(class2.a);
System.out.println(class1==class2); //结果是false说明class1和class2所指向的不是同一个对象,注意:引用之间的比较并不是比较引用所指对象的值是否相同,而是比较这两个引用是否指向同一个对象
}
}
class AClass implements Cloneable{//想要使用Object的clone方法就必须写出Cloneable接口,该接口中并没有任何方法,仅用作使用Object的clone方法之前的一个检测,若不写implements Cloneable则会抛出异常
public int a = 0;
public Object clone(){
AClass o = null;
try{
o = (AClass)super.clone();//调用Object的clone方法
}catch(CloneNotSupportedException ex){
ex.printStackTrace();
}
return o;
}
}
输出结果
12
false
注意
- 若希望我们的对象能提供clone功能,那么该类就要实现cloneable接口,即实现clone方法
- Object类的clone方法是protected的,因此不能在外面直接调用,而重新实现以后改为了public的,因此可以在main函数中直接使用
- clone方法得到对象的效率比new更快
浅拷贝与深拷贝
public class ShallowClone {
public static void main(String[] args){
BClass class1 = new BClass();
class1.a = 15;
System.out.println(class1.a); //15
System.out.println(class1.obj); //自动调用CClass里面的toString函数 11
BClass class2 = (BClass)class1.clone();
System.out.println(class2.a); //15
System.out.println(class2.obj); //11
class2.a = 22;
class2.obj.change();
System.out.println(class1.a); //15
System.out.println(class1.obj); //11
System.out.println(class2.a); //22
System.out.println(class2.obj); //23
}
}
class CClass implements Cloneable{
public int a;
public CClass(int a){
this.a = a;
}
public void change(){
a = a + 12;
}
public String toString(){
return "A Value is " + this.a;
}
public Object clone(){
CClass object = null;
try{
object = (CClass)super.clone();
}catch(CloneNotSupportedException ex){
ex.printStackTrace();
}
return object;
}
}
class BClass implements Cloneable{
public int a = 12;
public CClass obj = new CClass(11);
public Object clone(){
BClass object = new BClass();
try{
object = (BClass)super.clone();
object.obj = (CClass)obj.clone();
}catch(CloneNotSupportedException ex){
ex.printStackTrace();
}
return object;
}
}
最关键的一句话
object.obj = (CClass)obj.clone();
若注释掉这句话,则完成了浅拷贝,浅拷贝就是说,仅完成了BClass这个类里面的成员变量的拷贝,而CClass这个类并没有拷贝,还是只有一份,加上这句话以后,就表示,在拷贝了BClass的成员变量和复制了CClass以后(此时内存中还只有一个CClass),又将CClass拷贝了一份并赋给了object的obj,当返回object的时候,就将拷贝返回回去了。
this和super关键字
- this是指向对象自己的引用,更具体地说,this指向了这个类new出来的实例
- super是指向该类的父类的引用,若没有显示继承,那么super就指向Object
- 子类可以用super调用父类的非private的成员函数,类可以用this调用自己所有的成员函数和成员变量
注意
this和super不能在static块中运行,因为,static是属于一个类的,而this和super是属于某个new出来的对象的