面向对象编程

Java语言是一种面向对象的编程语言,号称一切皆对象。面向对象语言就会存在三个特性,封装,继承和多态。

封装

封装将代码的实现细节封装在类中,对外只暴露公共的接口。Java中的封装是通过private等权限修饰符来实现的。
标准JavaBean

public class Student {
    private int age;
    private String name;
    
    public Student(){}

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

标准的JavaBean应该拥有三个特性

  • 必须是一个公开的类,public类型的
  • 必须拥有无参构造函数
  • 属性用private修饰,通过getter和setter方法暴露给外界

继承

好处和弊端

  • 好处
    1、提高了代码的复用性
    2、提高了代码的维护性
    这皆是因为子类可以使用父类的属性和方法,可以减少重复代码,并且在维护的时候只需要修改一个地方就可以了。
  • 弊端
    1、继承是通过连接类与类,类的耦合性增强了,容易造成高耦合,在更改代码的时候,很难解耦合。

变量的访问特点

子类中变量的访问采用的是就近原则

  • 子类局部范围找
  • 子类成员范围找
  • 父类成员范围找
  • 没有就报错

this&super

this指代本类对象的引用,super代表父类存储空间的标识。
继承中子类可以通过super调用父类的属性和方法。

构造方法的访问特点

子类中所有的构造方法默认都会访问父类中无参的构造函数。
因为子类可能会使用父类的属性和方法,所以在子类初始化之前,必须先初始化父类。所以子类构造方法的第一条语句默认都是super(),如果没有,则会由编译器自动添加。
如果父类没有无参构造函数,则在继承的时候必须通过super显示的调用父类的有参构造函数,或者父类提供无参构造函数。否则无法初始化父类,导致报错。

方法访问的特点

  • 子类成员范围找
  • 父类成员范围找
  • 否则报错

内存图

对象在堆内存中创建,子类创建的对象会单独存在一块super的区域,用来存放父类的数据。
面向对象编程_第1张图片

方法重写

Java中有方法重写和方法重载

  • 方法重载发生在同一个类中,说的是在同一个类中,可以定义多个同名的方法,方法名相同,参数列表不同,这样的方法属于方法重载。
  • 方法重写发生在父类和子类中。当父类的方法不满足需要,可以在子类中定义同名、同参数列表的方法,子类使用该方法时,会覆盖父类的方法。

方法重写的注意事项

  • 私有方法不能够被重写,因为父类私有成员是子类不能继承的(两同)
  • 子类的访问权限不能降低(两小)
  • 子类抛出的异常不能更高
  • 子类的返回值类型小于或等于父类(一大)

阻断继承

使用final类和final方法可以阻断继承。
使用final修饰的类,成为最终类,不能继承。定义为final的类,其中的所有方法都自动成为了final类型的。
被final修饰的类和方法主要原因就是:确保它们不会在子类中改变语义
如果方法很简短,被频繁调用而且确实没有被覆盖,那么即时编译器就会将这个方法进行内联处理,如果方法被覆盖,则会取消对方法的内联。

多态

多态可以分为编译时多态和运行时多态,编译时多态指的就是方法重载。运行时多态是这里讲的多态,指的是在不同时刻表现出来的不同形态。
多态的前提

  • 要有继承或实现关系
  • 要有方法重写
  • 父类引用指向子类对象

多态中的成员访问特点

  • 成员变量
    编译看父类,运行看父类
  • 成员方法
    编译看父类,运行看子类
public class test {
    public static void main(String[] args) {
        Animal animal = new Cat();
        System.out.println(animal.age);
        System.out.println(animal.getAge());
    }
}

class Animal {
    int age = 20;

    public int getAge(){
        return this.age;
    }
}

class Cat extends Animal{
    int age = 10;

    public int getAge(){
        return this.age;
    }
}

输出
20
10

多态的好处和弊端

  • 好处
    提高程序的扩展性。定义方法的时候,使用父类作为参数,在使用的时候,使用具体的子类性参与操作,在方法参数中比较常见。
  • 弊端
    不能使用子类的特有成员

多态中的转型

  • 向上转型
    父类引用指向子类对象就是向上转型
  • 向下转型
    当需要使用子类特有成员时,需要将对象转成特有的子类类型。子类型 对象名 = (子类型)父类引用;
    在Java中,子类引用的数组可以转换成超类引用的数组,而不需要使用强制类型转换。
Child child = new Child();
Parent parent = child;

但这种使用会破坏语义,因为可以父类数组存储子类的元素,这样会产生矛盾的语义。

方法调用

1、编译器查看对象的声明类型和方法名。编译器此步知道了所有可能被调用的方法。
2、编译器确定方法调用中提供的参数类型。如果存在重载方法,则会找到一个参数匹配的方法,这个过程称为重载解析。如果没有匹配的,则会报错。
3、对于private、static和final方法,编译器可以在编译时期确定,这用称为静态绑定。
而像多态中的方法调用,调用的方法依赖于隐式参数的实际类型,必须在运行时动态绑定。
4、对于动态绑定的方法,虚拟机会调用对象所引用的实际类型对象的方法。

但是每次调用方法都需要完成整个搜索,时间开销特别大,所以虚拟机预先为每个类计算了一个方法表,其中列举了所有方法的签名和要调用的实际方法。在真正调用的时候,就直接在方法表中查找就行了。
那么实际的调用方法过程为:
1、虚拟机获取对象的实际类型的方法表
2、虚拟机查找定义了相应方法签名的类
3、虚拟机调用对应方法

你可能感兴趣的:(#,Java基础知识,java)