JAVA
一、Java面向对象的学习三条主线
- JAVA类及类的成员:属性,方法,构造器,内部类,代码块。
- 面向对象的特征:封装性,多态性,继承性。
- 其他关键字:this,super,static,final,abstract,interface,package,import。
二、局部变量不能使用权限修饰符
- 局部变量没有初始化默认值,调用局部变量前必须显式赋值。
- 局部变量放在栈里面。
- 方法的使用中,可以调用当前类的属性和方法(特殊的:方法A中又调用了方法A:递归方法)
一些小tips
1、方法的重载:”两同一不同“:同一个类,相同的方法名。参数不同,参数个数不同,参数类型不同。
2、判断是否是重载:跟方法的权限修饰符,返回值类型,形参变量名,方法体都没有关系。
3、如果参数是基本数据类型,此时实参赋值给形参的是实参真实存储的数据,如果参数是引用类型的数据类型,此时实参赋值给形参的是实参存储的数据值。
4、各修饰符权限说明图:
修饰符 | 类内部 | 同一个包 | 不同包子类 | 同一工程 |
---|---|---|---|---|
private | yes | |||
default(缺省) | yes | yes | ||
protected | yes | yes | yes | |
public | yes | yes | yes | yes |
四种权限都可以用来修饰类的内部结构,属性,方法,构造器,内部类,修饰类的话,只能使用public,缺省。
5、this(本类)调用构造器
- 我们在类的构造器中,可以显式地使用”this(形参列表)”方式,来调用指定类的其他构造器。
- 构造器中不能通过this(形参列表)来调用自己。
- 如果一个类中有N个构造器,则最多有n-1个构造器中使用了”this(参数列表)“。
- 规定”this(参数列表)“必须生命在当前构造器的首行。
- 构造器内部,最多只能声明一个”this(形参列表)“,用来构造调用其他构造器,可以调用的结构”属性,方法,构造器。 this调用的属性方法:理解为当前对象或者正在创建的对象。
6、JAVA Bean:是指符合以下标准的JAVA类:
类是公共的
一个无参的公共构造器
属性,且对应的get,set方法。
三、方法的重写
1、重写:子类继承父类以后,可以对父类中的同名参数的方法,进行覆盖操作。
2、应用:重写以后,当创建子类对象以后,通过子类对象调用父类中的同名同参数方法时,实际执行的是子类重写的父类方法。
3、重写规定:子类重写方法名和形参列表与父类被重写的方法名和形参列表相同。子类重写的方法的权限修饰符不小于被重写的方法的权限修饰符。
特殊情况:子类不能重写父类中声明为private权限的方法。
4、返回值类型:父类被重写的方法返回值为void,子类也为void。父类被重写的方法返回值为A,则子类重写的返回值类型可以是A类型或者是A的子类。如果父类被重写的方法返回的是基本数据类型,则子类的返回值类型必须是相同的基本数据类型。子类重写的方法抛出的异常类型不大于父亲被重写的方法抛出的异常类型。子类和父类中同名同参数的方法要么都申明为static类型(不是重写),要么都为非static类型,只有非static的重写才叫重写。
5、super关键字:
- 理解为父类的。
- 可调用属性、方法、构造器。
- 可在子类中使用super方法,显式地调用父类中声明的属性,方法,当同名属性时,必须用super。
- super(形参列表)的使用,必须声明在子类构造器首行。
- this和super在一个类中构造器 只能有一个。
- 构造了儿子必定构造了父亲(先有父后有子):当我们通过子类的构造器创建子类的对象时,我们一定会间接地调用父类构造器,进而调用父类的父类构造器,直到调用object类的构造器为止。
明确:虽然创建子类对象时,调用了父类构造器,但自始自终就只会创建一个对象。
四、多态性
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际运行的是子类中重写的方法,编译看左边,运行看右边。
1、多态的使用:虚拟方法的调用。
多态性的使用前提:类的继承关系,方法的重写
2、对象的多态性只适用于方法,不适用于属性。
重载与重写:从编译角度看:重载,是指允许多个同名方法,而这些方法的参数不同,编译器根据方法不同的参数表,对同名方法名称做修饰,对于编译器而言,这些同名方法就成了不同的方法,他们的调用地址在编译期就绑定了,java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。所以,对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定“或者”静态绑定“。
而对于多态而言,只有等到方法调用那一刻,解释运行器才会确定所要调用的具体方法,这称为”晚绑定“或者”静态绑定“。引用xx的一句话:不要犯傻,如果他不是晚绑定,它就不是多态。
五、equals 和 == 的区别:
- = =既可以比较基本类型也可以比较引用类型,对于基本类型就是比较值,对于引用类型就是比较地址值。
- equals的话,它是属于Java.lang.Object类里面的方法,如果该方法没有被重写过,默认也是==,我们可以看到String类等的equals方法是被重写过的,而且String类在日常开发中用的人较多,久而久之形成了equals是比较地址值的错误观点。
- 具体要看自定义类里面有没有从写Object类的equals方法来判断。
- 通常情况下,重写equals方法,会比较类中的相应属性是否都相等。
public void test(){
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i==j); //false 比较地址值
Integer m = 1;
Integer n = 1;
System.out.println(m==n); //true 自动转化为类,比较地址。
Integer x = 128;
Integer y = 128;
System.out.println(x==y);//true
/*Integer内部定义了IntegerCache结构,InteferCache定义了Integer[],保存了-128到127范围的整数,如果我们使用自动装箱,给Integer赋值范围在-128到127范围中时可以直接使用,而不用new,目的是提高效率。
*/
}
六、toString()
- Object中的toString()的定义为:类+@+地址值。
- 像String、Date、File、包装类都重写了Object类中的toString(),使得在调用对象时,返回实体内容的信息。
七、包装类的使用
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
八、static关键字
- static可以用来修饰:属性、方法、代码块、内部类
- 使用static修饰属性:按是否使用static修饰,又分为:静态属性和非静态属性。
- 实例变量:我们创建子类的多个对象,每个对象都独立具有一套类中的非静态属性,当修改其中一个对象中的非静态属性时,不会导致其他对象中的同样属性值得修改。
静态变量:多个对象共享同一个静态变量。
- static修饰属性的其他说明:
静态变量随着类得加载而加载,可以用过类.静态变量调用
静态变量得加载要早于对象得创建。
静态方法:随着类的加载而加载,可通过类.静态方法调用
1、静态方法中,只能调用静态方法或者静态属性。
2、非静态方法中,既可调用非静态方法或者属性,也可调用静态方法或者属性。
操作静态属性得方法:一般声明为static。
工具类中的方法,习惯上声明为:static,必如Math,Arrays,Collections。
类中的常量也声明为static。
九、饿汉式,懒汉式
饿汉式:坏处:对象加载时间过长。
好处:饿汉式是线程安全的。
懒汉式:坏处:延迟对象的创建。
好处:线程不安全。
//饿汉式:
class Bank{
private Bank(){}
private static Bank instance = new Bank();
public static Bank getInstance(){
return instance;
}
}
//懒汉式:
class Order{
private order(){}
private static order instance = null;
public static Order getInstance(){
instance= new Order();
return instance;
}
}
十、代码块
作用:用来初始化类或者对象。代码块如果有修饰类,只能用static修饰。
静态代码块:可以有输出语句
static{
//随着类得加载而执行(只执行一次)
}//初始化类得属性
//非静态代码块:随着对象的创建而执行(每创建一次执行一次),作用:可以在创建对象时对对象的属性初始化。
可以对对象属性赋值的位置:
- 默认初始化
- 显式初始化
- 构造器初始化
- 有了对象以后,通过对象,属性或者对象.方法进行。
- 在代码块中赋值
- 由父及子,静态先行。
十一、final关键字
final关键字可以用来修饰的结构:类(修饰后无子类)、方法(修饰后不能被重写)、变量(常量,名称大写,只能赋值一次)
十二、abstract
abstract修饰类:抽象类,不能实例化,抽象类中一定有构造器,便于对象子类对象实例化过程。
abstract修饰方法:抽象方法:
抽象方法只有方法的声明,没有方法体。
包含抽象方法的类,一定是抽象类,反之,抽象类中可以没有抽象方法若子类重写了所有抽象方法后,此方法方可实例化,若子类没有重写父类中所有抽象方法,此子类也是个抽象类。
abstract不能用来修饰属性,构造器等结构
abstract不能用来修饰私有方法,静态方法,final方法。
//创建匿名子类的对象:P Person为抽象类
Person p = new Person(){
@overide
public void eat(){
}
};
十三、接口
1、一方面,有时候需要从几个类中派生出一个类,继承他们的所有属性和方法,但是JAVA不支持多重继承,有了接口,就可以得到多重继承的效果,另一方面,有时候必须从几个类中抽取出一些共同的行为特征,而他们之间又没有is-a的关系,仅仅是具有相同的行为特征而已。例如:键盘,鼠标等usb接口
2、接口就是规范,体现现实中的”如果你是/要…则必须能“的思想,继承是一个”是不是“的关系。
十四、线程
Synchronized与Lock的对比:
1、Lock是显示锁(手动开启和关闭锁,别忘记关锁),synchronized是隐式锁,出了作用域自动释放。
2、Lock只有代码块锁,synchronized有代码块锁和方法锁。
3、使用Lock锁,java将花费较少的时间来调度代码,性能更好。并且有更好的扩展性(提供更多子类)。。