java基础知识点04_面向对象
面向对象编程OOP 的本质就是:以类的方式组织代码,以对象的形式封装数据
面向对象三大特性:封装、继承、多态
对象是具体的,类是对对象的抽象,描述对象的共同特征,是对象创建的模板,对象是类的一个具体实例,类实例化得到对象,每个类都有默认的无参构造方法,类实例化得到对象就是通过构造方法完成的,一旦定义了有参构造,无参构造就必须显示定义
- 对象(具体):小明、小红、李华
- 类(抽象):学生
定义静态方法:
public class Student {
public static void say() {
System.out.println("speaking....");
}
}
调用静态方法:
public class demo01 {
public static void main(String[] args) {
Student.say();
}
}
定义非静态方法:
public class Student {
public void say() {
System.out.println("speaking....");
}
}
调用非静态方法:
public class demo01 {
public static void main(String[] args) {
Student student = new Student();
student.say();
}
}
类的静态方法是和类一起加载的,而类的非静态方法是类实例化之后才存在的
所以调用非静态方法必须先实例化类,通过实例化的对象来调用方法!
值传递和引用传递:
- 值传递
public class demo01 {
public static void main(String[] args) {
int a = 1;
System.out.println(a);
demo01.change(a);
System.out.println(a);
}
public static void change(int a) {
a = 10;
}
}
结果a的值并没有改变!
- 引用传递
public class demo01 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);
demo01.change(person);
System.out.println(person.name);
}
public static void change(Person person) {
person.name="BLU";
}
}
class Person{
String name;
}
结果Person.name的值改变了!
创建对象时的内存分析:
public class Pet {
public String name;
public int age;
public void bark(){
System.out.println("barking....");
}
}
public class demo {
public static void main(String[] args) {
Pet dog = new Pet();
dog.name = "格洛米";
dog.age = 3;
dog.bark();
System.out.println(dog.name);
System.out.println("dog.age");
Pet cat = new Pet();
cat.bark();
}
}
对象初始化时属性的默认值:
数字类型:0 或 0.0
字符类型:u0000
boolean:false
引用类型:null
面向对象三大特性 —— 封装
将属性私有化,通过 get/set 方法操作属性
好处:保护数据,提高安全性。隐藏代码的实现细节
示例:
public class Student{
private String name;
private int age;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
}
public class demo {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("BLU");
System.out.println(s1.getName(););
}
}
面向对象三大特性 —— 继承
类是对对象的抽象,继承是对类的抽象
人类 —> 学生类、老师类
使用 extends 关键字继承
public class Student extends Person{
}
子类会继承父类的全部的 public 方法和属性
所有的类都直接或间接继承 Object 类
只能有一个父类
super 代表父类
this 代表本类
super() 调用父类的构造
this() 调用本类的构造
子类的构造器会首先调用父类的构造器
面向对象三大特性 —— 多态
静态方法和非静态方法的区别:
public class B {
public static void test() {
System.out.println("B....test");
}
}
public class A extends B{
public static void test() {
System.out.println("A....test");
}
}
public class test {
public static void main(String[] args) {
A a = new A();
a.test();
B b = new A();
b.test();
}
}
结果:
A....test
B....test
如果将A和B的test方法去掉static修饰,结果将变为:
A....test
A....test
静态方法与静态成员变量一样,属于类,在类装载的时候被装载到内存,一直存在,直到JVM关闭。
实例化方法,属于实例对象,实例化后才会分配内存,必须通过类的实例来引用。不会常驻内存,当实例对象被JVM 回收之后,也跟着消失。
instance of 判断对象类型
Object object = new Student();
object instanceof Student true
object instanceof Person true
object instanceof Object true
object instanceof Teacher false
object instanceof String false
父子类类型转换:
//子转父,子类的特有方法丢失
Person person = new Student();
//父转子,需要强制转换
Student student = (Student) new Person();
抽象类:
使用 abstract 修饰的类叫 抽象类
在抽象类中用 abstract 修饰的方法叫 抽象方法
抽象方法只有方法名,没有 方法体
继承抽象类的子类,如果不是抽象类,则 必须实现 父类的所有抽象方法
子类只能继承一个抽象类
抽象类 不能实例化
抽象类中可以有普通方法
接口:
比抽象类更抽象的抽象,相当于没有普通方法的抽象类
使用 implements 实现接口,可实现多个接口
实现类必须实现接口的方法
jdk8新特性:接口也可以提供具体方法,但需要 default 修饰:
public interface demo {
public default void test() {
System.out.println("test...");
}
}
final
final 修饰的类无法被继承
final 修饰的方法,子类无法重写
final 修饰的基本类型变量只有一次赋值机会
final 修饰的引用只有一次指向的机会
Object类
Object类是所有类的父类
toString()
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
getClass().getName()代表返回对象所属类的包名.类名
Integer.toHexString(hashCode())代表将对象的哈希值用16进制表示
finalize()
当一个对象没有任何引用指向的时候,它就满足垃圾回收的条件
当它被垃圾回收的时候,它的finalize() 方法就会被调用
finalize() 不是开发人员主动调用的方法,而是由虚拟机JVM调用的
equals()
Object.class:
public boolean equals(Object obj) {
return (this == obj);
}
String.class:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
equals和==的区别:
对于基本数据类型,==判断的是两个值是否相等
对于引用类型而言,==判断的是两个引用是否指向同一个对象
equals在Object类中本质上就是==,
而在String、Integer这些类中,equals方法被重写为值比较
String s1="apple";
String s2="apple";
String s3 = new String("apple");
String s4 = new String("apple");
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
System.out.println(s3==s4);
System.out.println(s3.equals(s4));
System.out.println(s1.equals(s3));
hashCode()
public native int hashCode();
hashCode方法返回一个对象的哈希值
线程同步相关方法:
wait()
notify()
notifyAll()
getClass()
public final native Class<?> getClass();
返回一个对象的类对象