02 Java面向对象特点介绍

本质

面向对象编程(Object-Oriented Programming,OOP),本质就是以类的方式组织代码,以对象的组织(封装)数据

面向过程是具体的、面向对象是抽象的。

抽象

三大特性: 封装、继承、多态

类和对象的关系

是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。

例: 动物、植物、手机…

Person类、Pet类、Cat类,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为。

对象是抽象概念的具体实例。

例:李四就是人的一个具体实例,李四的狗狗jack就是Cat的一个具体实例

能够体现出特点,展现出功能的是具体的实例,而不是抽象的概念

创建与初始化对象

使用new关键字创建对象

使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。

类中的构造器也称为构造方法,是在进行创建对象的时候必须调用的。并且构造器有以下两个特点:

  • 必须和类的名字相同
  • 必须没有返回类型,也不能有void

构造器

  • 使用new关键字,本质是调用构造器,必须使用构造器
  • 用来初始化值

一旦定义了有参构造,如果想使用无参构造,必须显示定义无参构造。

封装

  • 该露的露,该藏的藏

设计程序追求“高内聚、低耦合”。高内聚指的是类的内部数据操作细节自己完成,不允许外部干涉;低耦合指的是尽暴露少量的方法给外部使用。

  • 封装(数据的隐藏)

    通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这成为信息隐藏。

属性私有(private),get/set

继承

本质是对某一批类的抽象,从而实现对现实世界的更好建模。

extends的意思是“扩展”,子类是父类的扩展。

注意:Java只有单继承,没有多继承。(一个儿子只能有一个爸爸,一个爸爸可以有多个儿子)

  • 继承是类于类之间的一种关系。除此之外,类与类之间的关系还有依赖、组合和聚合

  • 继承关系是两个类。一个父类(基类),一个子类(派生类),子类继承父类使用extends来表示

  • 子类和父类之间,从意义上讲应该是“is a“ 的关系

私有的父类属性不能继承。(可以通过get/set来实现继承)

子类调用父类使用super

public class Stu extends Person{
    private String name = "Halo";
    public void test(String name){
        //这里的name是调用的test的形参name
        System.out.println(name);
        //这里的name调用的Stu类中的私有属性name
        System.out.println(this.name);
        //这里的name调用的是父类的name属性
        System.out.println(super.name);
    }
}

执行过程:子类的无参构造中有隐藏的super,所以调用父类的构造器,必须要在子类构造器的第一行。

super注意点

  1. super调用父类的构造方法,必须在构造方法的第一个
  2. super必须只能出现在子类的方法或者构造方法中
  3. super和this不能同时出现在构造方法中

super和this的区别

代表的对象不同:

  • this:本身调用者这个对象
  • super:代表父类对象的应用

前提:

  • this:没有继承也可以用
  • super:只能在继承条件下才可以使用

构造方法:

  • this(); 本类的构造
  • super(); 父类的构造

方法的重写

重写都是方法的重写,和属性无关!@Override

静态方法和非静态方法区别非常大!

静态方法:方法调用只和左边定义的数据类型有关。

重写之和非静态有关系!

因为静态方法

class A extends B{
    public static void test(){
        system.out.println("A->test");
    }
}
class B{
    public static void test(){
        system.out.println("B->test");
    }
}
public static void main(String[] args){
    A a = new A();
    a.test();  //输出A->test
    B b = new A();
    b.test();   //输出B->test
}
class A extends B{
    @Override
    public void test(){
        system.out.println("A->test");
    }
}
class B{
    public void test(){
        system.out.println("B->test");
    }
}
public static void main(String[] args){
    A a = new A();
    a.test();  //输出A->test
    B b = new A();
    b.test();   //输出A->test
}

重写:需要有继承的关系,子类重写父类的方法!

  1. 方法名必须相同
  2. 参数列表必须相同
  3. 修饰符:范围可以扩大但不能缩小: public-> protected -> default ->private
  4. 抛出的异常:范围可以缩小,但不能扩大:ClassNotFoundException -> Exception

重写:子类的方法和弗雷德必须一致,方法体不同!

Why需要重写?

A:父类的功能,子类不一定需要或者不一定满足!

多态

即同一个方法,可以根据发送对象的不同而采用不同的行为方式。

一个对象的实际类型是确定的,但是可以指向对象的引用的类型有很多。

  1. 多态是方法的多态,属性没有多态!
  2. 父类和子类有联系, 没有关系的会报出类型转换异常!ClassCastException
  3. 存在的条件:
    • 继承关系
    • 子类重写父类的方法,以下方法不会被重写:
      • static 方法属于类,不属于实例
      • final 常量
      • private 方法
    • 父类的引用指向子类 Father F = new Son();

static关键字

public class Person{
    {
        System.out.println("匿名代码块")}
    static{
        System.out.println("静态代码块")}
    public Person(){
        System.out.println("构造方法")}
    public static void main(String[] args){
        Person person = new Person();
    }
}

执行结果:

​ 静态代码块

​ 匿名代码快

​ 构造方法

public class Person{
    //赋初始值
    {
        System.out.println("匿名代码块")}
    //只执行一次
    static{
        System.out.println("静态代码块")}
    public Person(){
        System.out.println("构造方法")}
    public static void main(String[] args){
        Person person1 = new Person();
        System.out.println("=============");
        Person person2 = new Person();
    }
}

执行结果:

​ 静态代码块

​ 匿名代码快

​ 构造方法

​ ==========

​ 匿名代码块

​ 构造方法

静态导入包

当只导入包中指定的方法,可以使用static关键字。例:

import static java.lang.Math.random;
public class Test{
    public static void main(String[] args){
        System.out.println(random());
    }
}

和下面的方式一样

import static java.lang.Math;
public class Test{
    public static void main(String[] args){
        System.out.println(Math.random());
    }
}

抽象类

是一种约束,有人能帮你实现。abstract,抽象方法,只有方法的名字,没有方法的实现!

  • 不能new这个抽象类,只能靠子类去实现它;约束!
  • 抽象类中可以写普通的方法
  • 抽象方法必须在抽象类中

接口

普通类:只能有具体实现

抽象类:具体实现和规范(抽象方法)都有

接口:只是规范,自己无法写方法~专业的抽象!约束和实现的分离:面向接口的编程(即可以实现多继承)

声明类的关键字是class,声明接口的关键字是interface

接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。如果你是猫,就必须会捉老鼠。

接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。

oo的精髓是对对象的抽象,最能体现这一点的就是接口,为什么我们讨论设计模式都是只针对具备了抽象能力的语言(比如c++,java,C#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。

作用

  • 约束
  • 定义一些方法,让不同的人实现
  • 方法默认都是public abstract
  • 常量默认都是public static final
  • 接口不能实例化,接口中没有构造方法
  • implements可以实现多个接口
  • 必须重写接口中的方法

内部类

内部类就是在一个类的内部定义一个类,比如,A类中定义一个B类,那么B类相对于A类来说就是称为内部类,而A类相对B类磊说就是外部类。

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类

成员内部类

通过这个外部类来实例化内部类

public class Outer{
    public class Inner{
        public void in(){
            System.out.println("这是内部类方法")}
    }
}
public class Test{
    public static void mian(String[] args){
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.in();
    }
}   

获取外部内的私有属性

public class Outer{
    private int age=10;
    public class Inner{
        public void in(){
            System.out.println("这是内部类方法")}
        public void getAge(){
            System.out.println(age);
        }
    }
}

局部内部类

public class Outer{
    public void method(){
        //在方法中在构建类
        class Inner{
            
        }
    }
}

异常机制

五个关键字:
try catch finally throw throws
throw 是语句抛出一个异常;throws 是方法抛出一个异常;

  • throw语法:throw <异常对象>
    在方法声明中,添加throws子句表示该方法将抛出异常。
  • throws语法:[<修饰符>]<返回值类型><方法名>([<参数列表>])[throws<异常类>]
    【其中:异常类可以声明多个,用逗号分割。】
  • 处理运行时异常,采用逻辑去合理规避同时辅助try-catch处理
  • 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
  • 对于不确定的代码,也可以加上try-catch,处理潜在的异常
  • 尽量去处理异常,切忌只是简单的调用printStackTrace()去打印输出
  • 具体如何处理异常,要根据不同的业务需求和异常类型去决定
  • 尽量添加finally语句去释放占用的资源
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章