「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」
1、类和对象
1-面向对象和面向过程的区别****
面向过程比面向对象性能高
原因①
面向对象的类调用需要初始化,开销比较大,比较耗费资源
原因②(主要原因)
Java是半编译语言,最终的执行代码并不是可以直接被 CPU执行的二进制机械码
而面向过程语言大多都是直接编译成机械码在电脑上执行
2-构造器的运行
- 构造器不能被重写,但可以被重载,所有我们可以看到一个类里可以有多个构造器
- 父类中必须有一个无参构造器
-
- 子类在执行构造方法之前,默认会使用
super()来调用父类的无参构造方法,帮助子类初始化 - 父类中没有无参构造方法就会编译报错。
- 子类在执行构造方法之前,默认会使用
- 构造器的作用和特点
-
- 构造对象
- 名字和类名相同
-
- 没有返回值
3-对象的创建
对象的创建使用的方法时构造器
使用的运算符是 new
对象相关名词——对象引用(栈内存)和对象实例(堆内存)
一个对象引用可以对应0~1个对象实例(一根绳子可以不系气球,也可以系一个气球)
一个对象实例可以对应1~n个对象引用(一个气球可以用 n根绳子系住)
4-类的四种变量
Java 变量就好像⼀个容器,可以保存程序在运⾏过程中的值,它在声明的时候会定义对应的数据类型
(Java 分为两种数据类型:基本数据类型和引⽤数据类型)。变量按照作⽤域的范围⼜可分为三种类
型:局部变量,成员变量和静态变量。
⽐如说, int data = 88; ,其中 data 就是⼀个变量,它的值为 88,类型为整形(int )。
局部变量
在⽅法体内声明的变量被称为局部变量,该变量只能在该⽅法内使⽤,类中的其他⽅法并不知道该变量。
public class LocalVariable {
public static void main(String[] args) {
int a = 10;
int b = 10;
int c = a + b;
System.out.println(c);
}
}
其中 a、b、c 就是局部变量,它们只能在当前这个 main ⽅法中使⽤。
注意事项:
- 局部变量声明在⽅法、构造⽅法或者语句块中。
- 局部变量在⽅法、构造⽅法、或者语句块被执⾏的时候创建,当它们执⾏完成后,将会被销毁。
- 访问修饰符不能⽤于局部变量。
- 局部变量只在声明它的⽅法、构造⽅法或者语句块中可⻅。
- 局部变量是在栈上分配的。
- 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使⽤。
成员变量
在类的内部声明,但在方法体外的变量成为成员变量。 需要先实例化类,然后通过类的实例访问。
\
public class InstanceVariable {
int data = 88;
public static void main(String[] args) {
InstanceVariable iv = new InstanceVariable();
System.out.println(iv.data); // 88
}
}
注意事项:
- 成员变量声明在⼀个类中,但在⽅法、构造⽅法和语句块之外。
- 当⼀个对象被实例化之后,每个成员变量的值就跟着确定。
- 成员变量在对象创建的时候创建,在对象被销毁的时候销毁。
- 成员变量的值应该⾄少被⼀个⽅法、构造⽅法或者语句块引⽤,使得外部能够通过这些⽅式获取实例变量信息
- 成员变量可以声明在使⽤前或者使⽤后。
- 访问修饰符可以修饰成员变量。
- 成员变量对于类中的⽅法、构造⽅法或者语句块是可⻅的。⼀般情况下应该把成员变量设为私有。通过使⽤访问修饰符可以使成员变量对⼦类可⻅;
- 成员变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是 false,引⽤类型变量的默认值是 null。
- 变量的值可以在声明时指定,也可以在构造⽅法中指定。
- 和类实例一样存放在堆中
静态变量
通过 static 关键字声明的变量被称为静态变量(类变量),它可以直接被类访问
public class StaticVariable {
static int data = 99;
public static void main(String[] args) {
System.out.println(StaticVariable.data); // 99
}
}
通过 类名.静态变量 就可以访问了,不需要创建类的实例。
注意点:
- 静态变量在类中以 static 关键字声明,但必须在⽅法构造⽅法和语句块之外。
- ⽆论⼀个类创建了多少个对象,类只拥有静态变量的⼀份拷⻉。
- 静态变量除了被声明为常量外很少使⽤
- 静态变量储存在静态存储区
- 静态变量在程序开始时创建,在程序结束时销毁
- 与成员变量具有相似的范围 可⻅性。但为了对类的使⽤者可⻅,⼤多数静态变量声明为 public 类型。
- 静态变量的默认值和实例变量相似。
- 静态变量还可以在静态语句块中初始化。
常量
在 Java 中,有些数据的值是不会发⽣改变的,这些数据被叫做常量——使⽤ final 关键字修饰的成员变量。常量的值⼀旦给定就⽆法改变!
作用
- 代表常数,便于修改(例如:圆周率的值, final double PI = 3.14 )
- 增强程序的可读性(例如:常量 UP、DOWN ⽤来代表上和下, final int UP = 0 )
public class FinalVariable {
final String CHEN = "沉";
static final String MO = "默";
public static void main(String[] args) {
FinalVariable fv = new FinalVariable();
System.out.println(fv.CHEN);
System.out.println(MO);
}
}
5-特殊类
枚举Enum
实际项目中的使用
大量实际使用枚举的地方就是为了替代常量。
以这种方式定义的常量使代码更具可读性 ,允许进行编译时检查,预先记录可接受值的列表,并避免由于传入无效值而引起的意外行为。
public enum PinType {
REGISTER(100000, "注册使用"),
FORGET_PASSWORD(100001, "忘记密码使用"),
UPDATE_PHONE_NUMBER(100002, "更新手机号码使用");
private final int code;
private final String message;
PinType(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
@Override
public String toString() {
return "PinType{" +
"code=" + code +
", message='" + message + ''' +
'}';
}
}
// --------------使用枚举类------------------------
System.out.println(PinType.FORGET_PASSWORD.getCode()); // 100001
System.out.println(PinType.FORGET_PASSWORD.getMessage()); // 忘记密码使用
System.out.println(PinType.FORGET_PASSWORD.toString()); // PinType{code=100001, message='忘记密码使用'}
\
6、常见的关键字
| 访问权限 | private | protected | public |
|---|---|---|---|
| 类、方法、变量修饰符 | abstract | class | extends |
| final | implements | interface | |
| implements | interface | native | |
| new | static | strictfp | |
| synchronized | transient | volatile | |
| 程序控制 | break | continue | return |
| do | while | if | |
| else | for | instanceof | |
| switch | case | default | |
| 错误处理 | try | catch | throw |
| throws | finally | ||
| 包相关 | import | package | |
| 基本类型 | boolean | byte | char |
| double | float | int | |
| long | short | null | |
| true | false | ||
| 变量引用 | super | this | void |
| 保留字 | goto | const |
continue、break、return的区别?
都是用于程序的循环、方法控制的关键字
continue
跳出当前循环,继续下一次循环
break
跳出整个循环体,执行循环下面的语句
return
跳出所在方法,结束该方法的运行
\
synchronized
synchronized是Java提供的一个并发控制的关键字。主要有两种用法,分别是同步方法和同步代码块。也就是说,synchronized既可以修饰方法也可以修饰代码块。
/**
* @author Hollis 18/08/04.
*/
public class SynchronizedDemo {
//同步方法
public synchronized void doSth(){
System.out.println("Hello World");
}
//同步代码块
public void doSth1(){
synchronized (SynchronizedDemo.class){
System.out.println("Hello World");
}
}
}
被synchronized修饰的代码块及方法,在同一时间,只能被单个线程访问。
2、面向对象三大特征
1-封装
将一个对象的属性隐藏(private) 在对象内部
对外提供(public)方法可以操作里面的属性
public class Student {
private int id;//id属性私有化
private String name;//name属性私有化
//获取id的方法
public int getId() {
return id;
}
//设置id的方法
public void setId(int id) {
this.id = id;
}
//获取name的方法
public String getName() {
return name;
}
//设置name的方法
public void setName(String name) {
this.name = name;
}
}
2-继承
继承是使用已存在的类定义作为基础建立新的类的技术
提高代码重用、系统的可维护性、提高开发效率
注意:
- 子类拥有父类所有属性和方法,但无法直接访问父类私有属性和方法
- 子类可以拥有自己的属性和方法,即子类可以扩展父类
- 子类可以用自己的方式实现父类的方法(重写)
3-多态
一个对象有多种状态
// 向上转型 父类类型 引用名 = new 子类类型();
Animal dog = new Dog(); //这个对象是“只可以访问 Animal对象里的方法”(狗作为动物的方法)
// 向下转型 子类类型 引用名 = (子类类型)父类引用;
Dog bog2 = (Dog)dog; //向下兼容、强制转换,以便调用 Dog对象的特有方法
多态的特点:
- 对象类型和引用类型之间具有继承(类)/实现(接口)的关系
- 引用类型变量调用的方法是父类的还是子类的,要在程序运行期间才能确定
- 多态不能调用“只在子类存在但在父类不存在”的方法
- 同一方法,优先执行子类重写的方法
4-Object对象常用方法
public final native Class<?> getClass()//native方法,用于返回当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写。
public native int hashCode() //native方法,用于返回对象的哈希码,主要使用在哈希表中,比如JDK中的HashMap。
public boolean equals(Object obj)//用于比较2个对象的内存地址是否相等,String类对该方法进行了重写用户比较字符串的值是否相等。
protected native Object clone() throws CloneNotSupportedException//naitive方法,用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象 x,表达式 x.clone() != x 为true,x.clone().getClass() == x.getClass() 为true。Object本身没有实现Cloneable接口,所以不重写clone方法并且进行调用的话会发生CloneNotSupportedException异常。
public String toString()//返回类的名字@实例的哈希码的16进制的字符串。建议Object所有的子类都重写这个方法。
public final native void notify()//native方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。
public final native void notifyAll()//native方法,并且不能重写。跟notify一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。
public final native void wait(long timeout) throws InterruptedException//native方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁 。timeout是等待时间。
public final void wait(long timeout, int nanos) throws InterruptedException//多了nanos参数,这个参数表示额外时间(以毫微秒为单位,范围是 0-999999)。 所以超时的时间还需要加上nanos毫秒。
public final void wait() throws InterruptedException//跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念
protected void finalize() throws Throwable { }//实例被垃圾回收器回收的时候触发的操作