JavaSE入门笔记(七)

Java面向对象(课程笔记)

    • 01 初识面向对象
        • 面向过程和面向对象
        • 什么是面向对象
    • 02 方法回顾和加深
    • 03 对象的创建分析
        • 类与对象的关系
        • 创建与初始化对象
        • 构造器详解
        • 创建对象内存分析
    • 04 面向对象三大特性
        • 封装
        • 继承
        • 多态
        • static详解
    • 05 抽象类和接口
        • 抽象类
        • 接口
    • 06 内部类及OOP实战

课程来源 狂神说Java

由于笔者本人有着c语言的学习基础,故Java等等学习笔记有很多省略之处,多用以自己复习巩固

01 初识面向对象

面向过程和面向对象

JavaSE入门笔记(七)_第1张图片

对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理

什么是面向对象

  • 面向对象编程(Object-Oriented Programming,OOP)
  • (记住)面向对象编程的本质就是:以类的方式组织代码,以对象的方式组织(封装)数据
  • 抽象
  • 三大特性:
    • 封装
    • 继承
    • 多态
  • 从认识论角度考虑,是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
  • 从代码运行角度考虑,是先有类后有对象。类是对象的模板。

02 方法回顾和加深

  • 静态方法伴随类加载就加载,而非静态方法需要实例化为对象才加载

静态方法(static):可以直接通过类名调用,类名.方法名
JavaSE入门笔记(七)_第2张图片
非静态方法:无法直接通过类名调用,对象名.方法名
JavaSE入门笔记(七)_第3张图片
如果不是都是静态方法或者非静态方法,不可相互调用,下图是错误情况:
JavaSE入门笔记(七)_第4张图片

基础类型存值,引用类型存地址

值传递:形参类型为基本数据类型,形参的值改变,实参未改变
JavaSE入门笔记(七)_第5张图片
引用传递:形参类型为类,形参为对象,引用对象,形参改变,实参也改变
JavaSE入门笔记(七)_第6张图片

JavaSE入门笔记(七)_第7张图片

03 对象的创建分析

类与对象的关系

JavaSE入门笔记(七)_第8张图片

创建与初始化对象

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

一个项目中应该只存在一个main方法,在该项目中,对其他类的定义不要有main方法
JavaSE入门笔记(七)_第9张图片
实例
JavaSE入门笔记(七)_第10张图片
运行结果
JavaSE入门笔记(七)_第11张图片

构造器详解

  • 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
    • 1、必须和类的名字相同
    • 2、必须没有返回类型,也不能写void
  • 构造器必须要掌握

IDEA打开class文件:将class文件导入目录
Project Structure -> Modules -> +Add Content Root -> 导入包含class文件的文件夹

  • 1、一个类即使什么都写,它也会存在一个方法(构造器):一个类即使什么都不写代码,在main方法中定义一个实例化对象,编译后,打开class文件可知,会默认初始化一个与方法同名的空方法,其实这就是一个构造器;故在类中与类同名的且没有任何类型的方法,是为构造器。
  • 2、使用new关键字,本质上是在调用构造器
  • 3、**有参构造:一旦定义了有参构造,无参就必须显示定于。**如果使用了有参构造,则要保留空的无参构造器,对象的创建需要再无参造器的存在
  • 4、构造器是用来初始化值的
  • Alt+Insert快捷生成无参/有参构造器
    调用的一个对象时,会自动且先运行无参构造器

JavaSE入门笔记(七)_第12张图片
JavaSE入门笔记(七)_第13张图片

JavaSE入门笔记(七)_第14张图片

创建对象内存分析

实例代码内存分析
JavaSE入门笔记(七)_第15张图片
1.类的代码信息先于方法区加载,字符串是常量(final),int型数据age不是,age不在常量池
JavaSE入门笔记(七)_第16张图片
2、执行main方法,故main方法首先加载进入栈,在栈最底下(最先进入,最后弹出),当main方法弹出时,栈结束了,程序也执行完毕
JavaSE入门笔记(七)_第17张图片
3、执行main方法中代码创建一个Pet类dog对象

我们通过Debug调试查看
JavaSE入门笔记(七)_第18张图片
然后加载Pet类的代码信息至方法区JavaSE入门笔记(七)_第19张图片
通过Pet类的信息,生成一个具体的dog对象,在栈中加载dog(只是引用对象名,本质在堆中生成和分配内存空间,实质是先在堆中加载,然后再在栈中加载)
JavaSE入门笔记(七)_第20张图片
继续执行main方法
JavaSE入门笔记(七)_第21张图片
补充:静态方法区
JavaSE入门笔记(七)_第22张图片
所有的对象都可以直接调用它
JavaSE入门笔记(七)_第23张图片
方法区属于堆(JDK7之前方法区在堆中,JDK8之后移至本地内存),栈里面都是方法和引用变量
JavaSE入门笔记(七)_第24张图片

04 面向对象三大特性

封装

JavaSE入门笔记(七)_第25张图片

封装大部分针对属性,少部分包括方法

Alt+Insert 可以自动生成get/set方法

这些get/set方法是可以自行定义的,参数列表的实现代码都可以自定义

特点:

  1. 提高程序的安全性,保护数据;
  2. 隐藏代码的实现细节;
  3. 统一接口;
  4. 系统可维护增加了。

JavaSE入门笔记(七)_第26张图片

继承

JavaSE入门笔记(七)_第27张图片

子类继承父类的所有public或者默认的default(通常省略default修饰词)属性(包括方法),private属性不能继承
JavaSE入门笔记(七)_第28张图片
JavaSE入门笔记(七)_第29张图片

四种修饰符:public protected default private

Ctrl+H,打开继承树,查看继承关系
JavaSE入门笔记(七)_第30张图片

在Java中,所有的类都默认继承object类

private修饰的,私有的东西无法被继承

super详解
类似于this,不过指的是上一级,this是用来调用当前这一级的属性,super是用来调用上一级的,即父类的属性
JavaSE入门笔记(七)_第31张图片

JavaSE入门笔记(七)_第32张图片
JavaSE入门笔记(七)_第33张图片
JavaSE入门笔记(七)_第34张图片
JavaSE入门笔记(七)_第35张图片

  • 如果定义了有参构造且不定义无参构造,那么无参构造就不会默认生成。如果父类的无参构造不存在,则在子类无参构造中的隐藏代码super()也运行不了,继而子类的无参构造也运行不了
  • 故一般来说,一个类如果写了有参构造,则必须要写上无参构造

或者也可以直接调用父类的有参构造,super(属性)
JavaSE入门笔记(七)_第36张图片
JavaSE入门笔记(七)_第37张图片

super注意点:

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

super 与 this 的不同点:

  1. 代表对象不同:
  • this : 本身调用者这个对象
  • super :代表父类对象的应用
  1. 前提不同:
  • this : 没有继承也能使用
  • 只能在继承条件下才可以使用
  1. 构造方法不同
  • this() :本类的构造
  • super() : 父类的构造

方法重写

  • 为什么要方法重写:
    父类的功能,子类不一定需要,或者不一定满足;

方法重写 只跟非静态方法有关

静态方法在类一加载就已经加载了,而非静态方法需要对象加载

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

静态方法实例
JavaSE入门笔记(七)_第38张图片

用Alt+Insert选择的Overdide…可以快捷生成重写方法

因为静态方法是类的方法,而非静态方法是对象的方法,即b是A new出来的对象,因此调用了A类对象的方法,不是A的类方法

static修饰符可以直接不需要创建类,是类的方法。直接 类名点 的方式可以在main方法中调用。

非静态方法实例

  • 默认调用
    下面代码中进行了方法重写,故调用的都是(子类)A类对象的text()方法,而这个方法中调用了父类的test()方法,即B的test()方法。

JavaSE入门笔记(七)_第39张图片

  • 不默认调用,自己定义
    调用也是不调用父类方法

JavaSE入门笔记(七)_第40张图片
小结

  1. 优先级是 类高于对象
  2. 静态方法:方法的调用只与左边、定义的数据类型有关,左边定义的是 类,不能重写
  3. 非静态方法:可以重写的只能是public非静态方法
  4. private私有方法不能重写
  5. 重写需要有继承关系,方法重写只能存在父子类之间,而且只能是子类重写父类的方法
  6. 方法名必须相同
  7. 参数列表必须相同
  8. 方法体可不同
  9. 修饰符:范围可以扩大,不可以缩小
    public -> protected ->default ->private
  10. 抛出的异常:重写可能会抛出异常,范围可以被缩小,但不能扩大,即重写异常范围不能大于父类。
    ClassNotFoundException(小) -> Exception(大)

在这里插入图片描述
JavaSE入门笔记(七)_第41张图片

JavaSE入门笔记(七)_第42张图片

多态

在这里插入图片描述
JavaSE入门笔记(七)_第43张图片

  • 一个对象的实际类型是确定的;
  • 可以指向的引用类型就不确定了:父类的引用指向子类,但是不可以是子类引用父类;
  • 子类重写了父类的方法,执行子类的方法;
    JavaSE入门笔记(七)_第44张图片
    JavaSE入门笔记(七)_第45张图片
  • 对象能执行哪些方法,主要看对象定义的类型,看左边,和右边关系不大;
  • 子类能调用的方法都是自己的或者继承父类的,如下例中的Student类,而父类可以指向子类,但不能调用子类独有的方法
    JavaSE入门笔记(七)_第46张图片
    JavaSE入门笔记(七)_第47张图片

多态注意事项:

  1. 多态是方法的多态,与属性无关;
  2. 父类和子类,有联系 类型转换异常,ClassCastException;
  3. 存在条件:继承关系,方法需要重写,父类引用指向子类对象-> Father f1 = new Student;
  4. 不能重写的方法:
    1. static 方法,属于类,不输于实例;
    2.final 方法,常量;
    3. private 方法。

instanceof : (类型转换)引用类型,判断一个对象是什么类型~
X instanceof Y --> 在编译通过的前提下,判断对象X是不是属于Y类,主要用右边的对象实际类型与判断的类型比较,是则返回true,否则返回false。
JavaSE入门笔记(七)_第48张图片
代码的运行分为编译和运行两步,是否会编译错误,主要看左边定义的类型与判断的类型有没有父子关系,有则编译通过,否则编译错误
JavaSE入门笔记(七)_第49张图片
JavaSE入门笔记(七)_第50张图片

类型转换
类型之间的转换:父 子
JavaSE入门笔记(七)_第51张图片JavaSE入门笔记(七)_第52张图片
子类转换为父类,可能丢失一些方法
JavaSE入门笔记(七)_第53张图片

小结:

  1. 父类引用指向子类对象;
  2. 把子类转换为父类,向上转型;
  3. 把父类转换为子类,向下转型:强制转换;
  4. 方便方法的调用,减少重复的代码!简洁

static详解

JavaSE入门笔记(七)_第54张图片
JavaSE入门笔记(七)_第55张图片
JavaSE入门笔记(七)_第56张图片
静态方法里可以调用静态方法,不能调用非静态方法,因为静态方法随着类加载已经加载,而非静态方法还未加载。
JavaSE入门笔记(七)_第57张图片
静态>匿名>构造

JavaSE入门笔记(七)_第58张图片
JavaSE入门笔记(七)_第59张图片
静态代码块:只执行一次
对象一创建先执行匿名代码块,再走构造方法块
匿名代码块常用来赋值初始值(赋初值)
JavaSE入门笔记(七)_第60张图片
JavaSE入门笔记(七)_第61张图片

05 抽象类和接口

抽象类

  • 正如ADT类型,你描述构造一种类,它是抽象的,再去用代码实现
    JavaSE入门笔记(七)_第62张图片
  • abstract,抽象方法,只有方法名字,没有方法的实现。

JavaSE入门笔记(七)_第63张图片

  • 抽象类的所有方法,继承了它的子类,都必须要实现它的方法,除非子类也是抽象类;
    JavaSE入门笔记(七)_第64张图片
  • Java的类是单继承的,extends是单继承,但是接口可以多继承

抽象类注意点:

  1. 不能new出来,只能靠子类去实现它:约束!
  2. 抽象类中可以写普通方法;
  3. 抽象方法必须在抽象类中;
  4. 子类继承父类后,需要通过父类的构造器来实例化,所以抽象类也存在构造器;
    抽象的抽象:约束!

接口

锻炼抽象的思维

JavaSE入门笔记(七)_第65张图片

  • 接口中所有定义的方法其实都是抽象的 public abstract,不在方法定义前加修饰符
  • 接口中定义的变量都是常量 public static final
    JavaSE入门笔记(七)_第66张图片
  • 接口都需要实现类,下面是一个实现类的例子
  • 如果要去实现接口里面的所有定义,实现类里面需要对接口的方法全部进行重写
  • 接口是可以多继承的,一个实现类可以继承多个接口
    JavaSE入门笔记(七)_第67张图片
    JavaSE入门笔记(七)_第68张图片
  • 接口的作用:
  1. 约束
  2. 定义一些方法,让不同的人实现
  3. 方法都是public abstract
  4. 属性变量都是public static final
  5. 接口不能别实例化,接口中没有构造方法
  6. implements可以实现多个接口
  7. 必须要重写接口的方法

06 内部类及OOP实战

JavaSE入门笔记(七)_第69张图片

  • 通过外部类来实例化内部了
    JavaSE入门笔记(七)_第70张图片
  • 内部类直接访问外部类的属性(包括私有属性private)
    JavaSE入门笔记(七)_第71张图片
  • 外部类实例化后加载,先加载静态属性,故先实例了内部类,非静态属性未加载,所以在加载内部类时调用了未加载的非静态属性,编译报错,把调用的该非静态属性改为静态就不会编译错误(解决方式之一)
    JavaSE入门笔记(七)_第72张图片
  • 一个Java类文件里只能有一个public class类,但是可以有多个class类,但这不是内部类
    JavaSE入门笔记(七)_第73张图片
  • 局部内部类,例如定义在方法里的类
    JavaSE入门笔记(七)_第74张图片

拓展
JavaSE入门笔记(七)_第75张图片

你可能感兴趣的:(入门学习,编程语言,java,多态,封装)