【Java基础】面向对象思想

137 阅读10分钟

「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

1、类和对象

1-面向对象和面向过程的区别****

面向过程比面向对象性能高

原因①

面向对象的类调用需要初始化,开销比较大,比较耗费资源

原因②(主要原因)

Java是半编译语言,最终的执行代码并不是可以直接被 CPU执行的二进制机械码

而面向过程语言大多都是直接编译成机械码在电脑上执行

2-构造器的运行

  1. 构造器不能被重写,但可以被重载,所有我们可以看到一个类里可以有多个构造器
  2. 父类中必须有一个无参构造器
    1. 子类在执行构造方法之前,默认会使用super()来调用父类的无参构造方法,帮助子类初始化
    2. 父类中没有无参构造方法就会编译报错。
  1. 构造器的作用和特点
    1. 构造对象
    2. 名字和类名相同
    1. 没有返回值

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、常见的关键字

访问权限privateprotectedpublic
类、方法、变量修饰符abstractclassextends
finalimplementsinterface
implementsinterfacenative
newstaticstrictfp
synchronizedtransientvolatile
程序控制breakcontinuereturn
dowhileif
elseforinstanceof
switchcasedefault
错误处理trycatchthrow
throwsfinally
包相关importpackage
基本类型booleanbytechar
doublefloatint
longshortnull
truefalse
变量引用superthisvoid
保留字gotoconst

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-继承

继承是使用已存在的类定义作为基础建立新的类的技术

提高代码重用、系统的可维护性、提高开发效率

注意:

  1. 子类拥有父类所有属性和方法,但无法直接访问父类私有属性和方法
  2. 子类可以拥有自己的属性和方法,即子类可以扩展父类
  1. 子类可以用自己的方式实现父类的方法(重写)

3-多态

一个对象有多种状态

// 向上转型 父类类型 引用名 = new 子类类型();
Animal dog = new Dog(); //这个对象是“只可以访问 Animal对象里的方法”(狗作为动物的方法)
// 向下转型 子类类型 引用名 = (子类类型)父类引用;
Dog bog2 = (Dog)dog;  //向下兼容、强制转换,以便调用 Dog对象的特有方法

多态的特点:

  1. 对象类型和引用类型之间具有继承(类)/实现(接口)的关系
  2. 引用类型变量调用的方法是父类的还是子类的,要在程序运行期间才能确定
  1. 多态不能调用“只在子类存在但在父类不存在”的方法
  2. 同一方法,优先执行子类重写的方法

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 { }//实例被垃圾回收器回收的时候触发的操作