注意
1、全局变量有默认值,可以不赋值,直接使用;局部变量没有默认值,必须赋值后才能使用。
2、静态方法static可以直接通过类名调用,不需要先创建对象:类.方法()
3、类什么时候被加载:
(1)创建对象实例时(new)
(2)创建子类对象实例,父类会先被加载
(3)使用类的静态成员时(静态属性或静态方法)
4、获取当前时间,可利用 结束时间-开始时间 计算所用的时间
t = System.currentTimeMillis();
++++++
一、数据类型转换
1、自动类型转换
精度小的自动转换为精度大的
int a = 'c';
double d = 80;
2、String类型转换
(1)基本类型转String类型:基本类型 + “”
int n = 100;
String s = n + "";
(2)String类型转基本类型:通过基本类型的包装类调用***parseXX()***方法
String s = "123";
int n = Integer.parseInt(s);
+++++
二、二维数组
二维数组的遍历
int[][] arr = new int[5][6];
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr[i].length; j++){
}
}
++++++
三、构造方法/构造器
在类中访问构造方法只能在构造方法中使用(即只能在构造方法中访问另一个构造方法)
访问构造方法的语法:this(参数列表)
注意:必须放在第一条语句
class T{
public T(){
this("Jack", 20); //访问另一个构造方法的语句必须放在第一条
}
public T(String name, int age){
this.name = name;
this.age = age;
}
}
+++++
四、访问修饰符
同类 | 同包 | 子类 | 不同包 | |
---|---|---|---|---|
public | ✔ | ✔ | ✔ | ✔ |
protected | ✔ | ✔ | ✔ | ✖ |
默认 | ✔ | ✔ | ✖(同包✔) | ✖ |
private | ✔ | ✖ | ✖ | ✖ |
+++++
五、继承extends
1、子类会默认调用父类的无参构造器,完成父类的初始化
创建子类对象时,不管使用子类的哪个构造器,默认会调用父类的无参构造。如果父类没有提供无参构造器,则必须在子类的构造器中用***super(参数列表)***去使用父类的哪个带参构造器,以完成对父类的初始化。(注意:***super(参数列表)必须放在子类构造器的第一行,因此super()与this()***不能共存在同个构造器中)
2、java是单继承机制,子类最多只能直接继承一个父类
++++++
六、多态
1、方法的多态
重载和重写就体现了多态
2、对象的多态
(1)一个对象的编译类型和运行类型可以不一致
(2)编译类型在定义对象是就确定了,不能改变;而运行类型可以改变
(3)编译看左边,运行看右边
(4)父类的引用可以指向(接收)子类对象
//Animal是父类,Dog是子类,Cat也是子类
Animal animal = new Dog(); //(1),向上转型,可以调用父类中的所有成员(遵守访问权限)(编译看左边);
//不能调用子类的特有员,但最终运行结果看子类的具体实现(运行看右边)
animal = new Cat(); //(2)
多态的向下转型:
(1)只能强转父类的引用,不能强转父类的对象
(2)要求父类的引用必须指向的是强转目标类型的对象
(3)向下转型后可以调用子类中的所有成员
Animal animal = new Cat(); //(2)
Cat cat = (Cat) animal;
**注意:**方法看运行类型(右边),属性看编译类型(左边)
a instanceof B //判断对象a是否为B类型或B的子类型
3、动态绑定机制
(1)当调用对象方法时,该方法会和该对象的内存地址/运行类型绑定
(2)对象属性没有动态绑定机制
class A{
public int i = 10;
public int sum(){
return getI() + 10;
}
public int getI(){
return i;
}
}
class B extends A{
public int i = 20;
public int getI(){
return i;
}
}
//main方法中
A a = new B();
a.sum(); //30 调用A中sum(),因为动态绑定机制,所以此时sum()中的getI()调用的是运行类型B中的
++++
七、== 与 equals的对比
1、== 是比较运算符
(1)== 既可以判断基本数据类型,也可判断引用类型
(2)== 基本数据类型,判断的是值是否相等,不看类型
(3)== 引用类型,判断的是地址是否相等,即判定是不是同一个对象
int it = 65;
float fl = 65.0;
it == fl //true
char ch = 'A';
it == ch //true
2、equals 是Object类中的方法,只能判断引用类型,默认判断地址是否相等。子类往往重写该方法,用于判断内容是否相等,例如Integer , String
(1)Object类 判断地址是否相等
(2)String类、Integer类 判断内容是否相等
class Student(){}
Student s1 = new Student();
Student s2 = new Student();
s1.equals(s2) //false
Integer it1 = new Integer(100);
Integer it2 = new Integer(100);
it1.equals(it2) //true
it1 == it2 //false
++++
八、toString
toString默认返回:全类名(包名+类名)+@+哈希值的十六进制
往往会重写toString方法,用于返回对象的属性信息
当直接输出一个对象时,会默认调用toString方法。例如,System.out.println(student);会默认调用student.toString()
++++
九、static
1、类变量/静态变量
类变量,是该类的所有对象共享的变量
类变量是随着类的加载而创建的,所以即使没有创建对象实例也可以访问
定义语法: 访问修饰符 static 数据类型 变量名
访问类变量: 类名.类变量名
或 任一对象名.类变量名
2、类方法/静态方法
类方法与上述类变量的特点一致
注意:(1)类方法不允许使用和对象有关的关键字,如this和super
(2)静态方法只能访问静态成员;非静态方法可以访问静态成员和非静态成员
(3)静态方法不能被重写
+++++
十、代码块
代码块,又称为初始化块,属于类中的一部分。相当于另一种形式的构造器,可以做初始化操作
使用场景:如果多个构造器都有重复的语句,可以抽取到代码块中,提高代码的复用性
语法:
static{ //有static修饰的叫静态代码块;没有static的叫普通代码块/非静态代码块
代码
}; // ; 号可写可不写
注意:
(1)static代码块随着类的加载而执行,并且只执行一次;普通代码块是在创建对象时,才会被执行,并且创建一次对象就执行一次,若只是使用类的静态成员,普通代码块并不会执行
(2)创建一个子类对象时,初始化调用的顺序:
1、父类的静态代码块和静态属性(代码块和属性优先级一样,按定义顺序执行)
2、子类的静态代码块和静态属性(代码块和属性优先级一样,按定义顺序执行)
3、父类的普通代码块和普通属性
4、父类的构造方法
5、子类的普通代码块和普通属性
6、子类的构造方法
+++++++++
十一、单例模式
单例模式,即单个实例,使某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
1、饿汉式
饿汉式在类加载就创建了对象实例,如果程序员没有使用这个对象实例,则浪费了资源
步骤:
(1)构造器私有化(防止直接new)
(2)在类内部创建一个对象
(3)提供一个公共的静态方法
class GirlFriend{
private String name;
private GirlFriend(String name){ //构造器私有化
this.name = name;
}
private static GirlFriend gf = new GirlFriend("小白"); //在类内部创建一个对象
public static GirlFriend getInstance(){ //提供一个公共的静态方法
return gf;
}
}
2、懒汉式
懒汉式在使用时才创建对象实例,但存在线程安全问题
步骤:
(1)构造器私有化
(2)定义一个static静态属性对象
(3)提供一个公共的静态方法
class Cat{
private String name;
private Cat(String name){ //构造器私有化
this.name = name;
}
private static Cat cat; //定义一个静态属性对象
public staric Cat getInstance(){ //提供一个公共的静态方法
if(cat == null){
cat = new Cat("小白");
}
return cat;
}
}