面向对象

 

 

面向对象(OOP)

1649148146717

 

面向过程&面向对象

面向过程:线性思维

面向对象:分类思想

1649148433434

  • 面向对象编程的本质:以类的方式组织代码,以对象的组织“封装”数据。

    • 属性+方法=类

      • 认识论:先有对象后有类。对象是具体的事物。类是抽象的,是对对象的抽象,将相似的部分抽象出来。

      • 代码运行角度(需要设计,分好类再去实现):先有类后有对象。类是对象的模板。

  • 三大特性:

    • 封装:将数据封装起来,只留一个外部访问接口。

    • 继承:子类继承父类。

    • 多态:同一类事物,因个体不同而有不同的形态

1649148467910

回顾方法以及加深

1649158948256

  • break:跳出switch语句、结束循环;

  • continue:跳过一次循环,回到下一次循环

  • return:返回方法的返回值,同时结束方法,方法中、return后,写代码无效

方法回顾

1649153853146

 

方法调用

1649155965481

  • 非静态可以调用静态和非静态

  • 非静态可以调用静态和非静态,因为在其中一个被实例化后,两个非静态的会被一起创建,同步加载

  • 非静态未实例化前,不占用空间资源

1649156836645

实参与形参

1649157294098

 

值传递与引用传递

  • 值传递:实参与形参在内存上是独立的两个变量

  • 引用传递(地址、指针):实参和形参在内存上指向的是同一个地址

  • 一个类里边只能有一个public class,但有多个class

1649158472412

1649158731199

 

类与对象

类与对象的关系

属性+方法=类

  • 编程时,先有类,才有对象

    • 当方法为static时,该方法与类一起创建,可以直接通过 ”类.方法“ 调用此方法。

    • 当方法为非static时,该方法并未初始化,需要先对其所在的类进行实例化,返回该类的一个对象(可以返回多个),才会被分配空间而创建从而真实存在(之前只是定义)。

      • 对象:实例化后的类返回的

      • 非static方法,在对应的类实例化为返回对象后,通过 “对象.方法0” 进行调用。

      • 对于对象,也可以使用 “对象.属性” 去对属性进行操作。

1649158987293

 

  • 以类的方式组织代码,以对象的形式封装具体的数据

1649164299836

 

构造器

1649163579630

一个类即使什么都不写,也会存在一个构造方法

1649165535547

  • 创建构造器,快捷键:alt+insert(insert与其他键复用时,需要按住fn或者shift去选中)

    • 选择Select None,会创建无参构造器

    • 前边写好属性后,构造时按住shift,可以多选参数,点击OK,则会创建重载的有参构造器

1649167314635

  • 有参构造器:一旦定义了有参构造,无参就必须显式定义,否则无效

  • 无参构造器

    • 类进行实例化的过程:需要先进入构造器,构造器走完,才会生成对象。

    • 实例化:要调用类中的非static变量或者方法,就必须先对类进行实例化为对象,采用 “对象.方法” 或 “对象.变量” 的方式调用。

    • 作用

      • 对实例化的值进行初始化

      • 使用new关键字,本质是在调用构造器

1649166007214

1649166688290

1649167699845

创建对象内存分析

栈用于存放变量与执行方法,堆用于加载方法与数据

步骤

  • step1:构建Application类与静态方法区

  • step2:进入main方法

  • step3:构建Pet类

  • step4:进行默认地无参构造,并给Pet类中参数初始化

PS:类进行实例化的过程:需要先进入构造器,构造器走完,才会生成对象。

  • step5:创建引用变量cat与dog,引用变量指向的地址内存

  • step6:继续执行main方法

  • step:根据main方法中的变量值与方法,对Pet类中数据进行赋值与方法执行

1649173276684

1649174182055

总结

  1. 类与对象

    • 类是一个模板:抽象;对象是一个具体的实例

  2. 方法

    • 定义、调用

  3. 对应的引用

    • 引用类型:对象是通过引用来操作的:栈--->堆(地址)

    • 基本类型(8):int、long、short、boolean、double、float、byte、char。

  4. 属性:字段Field 成员变量

    • 默认初始化:

      • 数字:0、0.0

      • char : u0000

      • boolean : false

      • 引用:null

    • 修饰符 属性类型 属性名 = 属性值!

  5. 对象的创建与使用

    • 必须使用new关键字创建对象,构造器 Person kuangshen = new Person();

    • 对象的属性 kuangshen.name

    • 对象的方法 kuangshen.sleep();

  6. 类:

    • 静态的属性 属性

    • 动态的行为 方法

 

三大特性

1649303843295

封装

  • 程序设计要追求:高内聚低耦合

    • 高内聚就是类的内部数据操作细节自己完成,不允许外部干涉

    • 低耦合:仅暴露少量的方法给外部使用。

    • 属性私有,get/set

1649227064108

  • 快捷键:alt+insert,快速设置set与get方法

1649228393020

1649229051519

1649229063158

 

继承

1649229317804

最终程序

1649234819621

1649234833398

1649234841926

  • 快捷键:ctrl+H,显示父子关系

  • 私有(private)的东西,无法被继承

在main中子类使用父类东西--单独程序

1649230517922

1649230523622

1649230529692

  • 在main中子类使用父类东西,需要将子类实例化,父类会在子类构造器中自动完成实例化,之后可以直接使用

1649233583974

    • 子类与父类东西不同,直接调用

1649233299697

    • 子类与父类东西(属性与方法)相同,就近调用

1649233606871

 

object类

在java中,所有的类,都默认直接或者简介继承object类

 

supper,对比this:在子类中调用父类东西

  • 子类实例化,父类会自动实例化

    • 写有参构造时,需要把无参构造显式地写出来,避免子类调用父类无参/有参出错

    • 程序最开始走到new类实例化时,就对子类与父类进行了初始化,而且是父类在前,子类在后

    1649234061186

    • 隐藏了代码——super();:子类的无参构造中调用了父类的无参构造,且显示写出super();时,必须写在第一行,否则报错

    1649234429377

    • 子类无参会默认调用父类无参,但如果父类是有参构造,子类也必须显式地写出调用父类的有参构造。

    • 子类中super和this不能同时调用构造方法!因为都需要在第一行。

  • 在子类中调用父类的东西,用super

1649233318314

总结

  • final修饰的类,无法被继承

  • super注意点:

    • 子类用super调用父类的构造方法,必须在构造方法的第一个。

    • super必须也只能出现在子类的方法或者构造方法中。

    • 子类中super和this不能同时调用构造方法!因为都需要在第一行。

  • VS this

    • 代表的对象不同:

      • this:本身调用者这个对象

      • super:代表父类对象的应用3

    • 前提:

      • this:没有继承也可以使用

      • super:只能在继承条件才可以使用

    • 构造方法

      • this():本类的构造

      • super():父类的构造

 

方法的重写

非static:会被重写,并且就近调用
  • 当子类方法名与父类方法名相同、且都为非static时,需要加入重写注解,进行方法重写

1649232413871

  • 快捷键,alt+insert可以直接重写方法,默认继承父类,但可以自己修改

1649250033751

1649250208123

  • 非static会被重写,并且就近调用,输出结果相同。

1649250435219

 

static:不能被重写,但是能够被再次声明。
  • 父类的引用转向了子类,new A()--子类的时候,会自动new B()--父类,B b说明此处实例化后的对象b属于B;

  • 但反之A c = new B();不行,因为new父类的时候,子类并未被实例化

1649249310901

  • static不能被重写,通过不同的实例化调用,因为无法实例化为对象,本质还是类,输出的结果不同,不执行就近原则

1649249785384

非静态与静态区别很大:
  • B b = new A();中,b是A new出来的对象,因此 b.test() 调用了A的方法。

  • 因为静态方法是类的方法,而非静态是对象的方法。

  • 有static时,方法可以直接通过 “类.方法” 调用,B类无需实例化(可以实例化为对象,但静态的不会走对 象.方法 的调用),b需要从B类去调用, b.test() 等价于B.test() ,b调用了B类的方法,因为b是用b类定义的。

1649251507941

  • 非static时,方法需要通过 “对象.方法” 去调用,B类需要被实例化为一个对象b.test() 等价于new A().test(),b调用的是对象的方法,而b是用A类new出来的。B b = new A();子类重写了父类的方法。

1649251630871

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

    • 方法名必须相同

    • 参数列表必须相同

    • 修饰符:范围可以扩大,但不能缩小。public>protected>default>private

    • 抛出的异常:范围可以缩小,但不能扩大。ClassNotFoundException---->Exception(大)

  • 重写,子类的方法要和父类一致;方法体不同!

  • 为什么需要重写:

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

    • alt+insert:override;

 

实时检测功能的问题:
  • 实时检测功能是开发规约插件的功能,根据公约不应该用类实例变量访问静态成员,所以报错

  • 但关闭实时检测后,不再报错

  • 不关闭,即使此处报错,也可以执行

  • 此处更新一个结论:静态成员变量,可以直接通过 类.方法 访问。也可以通过实例变量的方式进行访问,但不应该。

1649248585127

1649248755243

多态:重写---->多态

1649257459395

代码

1649257338143

1649257344535

1649257353719

 

父类与子类的多态

  • 一个对象的实际类型时确定的;但可以指向这个对象的引用类型就不确定了,父类的引用指向子类。

1649256955827

  • 对象能执行哪些方法,主要看对象左边的类型,和右边关系不大

    1649256319226

  • 对s1,左边是student(子类),则要看子类有没有对应的函数:

    • 若有则直接执行自己的

      有test,则test执行自己的

      1649256596785

    • 若没有的看能否继承父类。

      无eat,但继承自父类

      1649256635154

    • 对s2,左边为person(父类),则看父类有没有对应函数

      • eat未被子类重写,则执行自己的

      1649256739047

      • run被子类重写,则执行子类的

      1649256771564

      • 父类无法调用子类,会被强制转换

      1649256828215

多态注意事项

  • 多态是方法的多态,属性没有多态

  • 父类和子类,有联系 若无联系,会类型转换异常! ClassCastException

  • 存在条件

    • 继承关系

    • 方法需要重写

      • 不可重写的

        • static 方法,属于类,它不属于实例

        • final 常量

        • private 方法;

    • 父类的引用指向的是子类对象! father f1 = new son();

instcanof与类型转换

instanceof
  • instanceof可以判断是否有父子关系。

1649302170041

  • System.out.println(X instanceof Y);

    • 能不能通过编译,看X与Y是否在一条族谱线

    • instanceof结果是true或者false,看是否有父子关系,并遵循向上转型

1649302267002

1649302184930

 

类型转换
  • 高转低,强制转换,父类调用子类的东西,强制转换后可以使用

  • 低转高,自动转换,但可能会丢失一些自己本来的方法!

1649303450959

1649303462772

1649303470404

总结
  • 总结:

    • 父类的引用指向子类的对象。

    • 把子类转换为父类,低转高,向上转型;可能会丢失子类本身的一些方法。

    • 把父类转化为子类,高转低,向下转型,需要强制转换。

    • 方便方法的调用,减少重复的代码!简洁

  • 抽象:封装、继承、多态! 抽象类,接口。

 

static

静态变量与非静态变量
  • 静态变量,可以直接用过类的形式在其他类调用,多用于需要多处类使用的变量;

  • 静态变量,用 类.对象 的形式调用,输入Student会默认显示age;但用实例变量形式,虽不会错,但输入s1不会会默认显示age;

  • 静态变量,不论是否实例化,都是属于类的,应采用类的形式去调用;

  • 非静态变量,必须对类进行实例化,采用 对象.变量 调用

1649331214829

 

静态方法与非静态方法
  • 静态方法可以直接调用,也可以用 类.方法 调用

  • 非静态方法,必须对类进行实例化,采用 对象.方法 调用

  • 静态方法只能调用静态方法,非静态方法可以调用静态、非静态方法。

 

静态代码块
  • 1 静态代码块,Person类加载时执行,永久只执行一次

  • 2 匿名代码块:在构造器之前、实例化对象时加载;可以用于赋初值,但程序无法直接调用该匿名代码块。

  • 3 构造方法,实例化对象时加载

1649332270227

静态导入包
  • 导入对应类的包后,可以直接调用里边的函数

1649332652228

 

抽象类--单继承

1649332909139

1649333566102

1649333572426

抽象方法

  • abstract,约束~有人帮我们实现~抽象方法,只有方法名字,没有方法的实现!

抽象类

  • abstract 抽象类:本质是类,需要继承extends 单继承~;接口可以多继承。

  • 继承了抽象类的子类,都必须要实现(重写)父类抽象类的所有方法~除非子类也是抽象类

  • 特点:抽象的抽象——就是一个约束

    • 不能new这个抽象类,只能考子类去实现它;约束!

    • 抽象类可以写普通的方法与抽象的方法

    • 但抽象的方法必须写在抽象类中

  • 思考题

    • 不能new,存在构造吗?----------存在,alt+insert可以直接写出来

    • 存在的意义?---------------抽象出来,提高开发效率,可扩展性更强

 

接口--多继承

Interface

1649334178532

  • Java单继承,但通过接口来实现“伪多继承”

1649335090763

  • 接口

    • interface 定义的关键字 接口都需要有实现类,重写其中的所有方法

    • 实现了接口的类,就需要重写接口中的所有方法~

      • 格式:类 可以实现接口 implements 接口

    1649335090763

    • 接口中所有东西都是抽象的

      • 如果不写修饰符,属性默认为常量~ 但一般不会在接口中定义常量

      • 如果不写修饰符,方法默认是public abstract;可以只写返回值类型、方法名、参数类型、形参

1649335174383

1649335183445

1649335190772

 

作用

  • 约束

  • 定义一些方法,让不同的人实现~

  • 方法都是public abstract

  • 属性都是public abstract final

  • 接口不能被实例化,接口中没有构造方法

  • implements可以实现多个接口

  • 实现接口的类,必须重写接口的方法

 

内部类

1649337499894

1、成员内部类:外部类的内部类

  • 内部类可以通过新建一个方法,在方法体内获得外部类的私有属性、方法

  • 但无法在外部直接使用,会报错

1649338663349

  • 内部类的实例化:通过外部类实例化后的对象去进行实例化

1649338775637

 

2、静态内部类

  • static在类加载时一起加载,此时还不存在外部类的属性,所以无法获取id与方法out()。

1649338982016

  • 且静态的类无法调用非静态的方法,静态只能调用静态

1649339431265

外部类的内部类与一个java类中的内部类不同

  • 一个java类中可以有多个classs类,但只能有一个public class类

1649339585608

 

3、局部内部类:方法中的内部类

1649339804836

  • 没有名字初始化类,不用将实例保存到变量中~

1649340047075

4、匿名内部类,接口相关:

  • 接口没法new,new的话实际是在创建一个实现它的匿名内部类,并重写方法

  • 实际会返回UserService userService = new UserService() {...}

1649340491311

 

 

posted @ 2022-04-07 22:15  尘世红叶  阅读(63)  评论(0)    收藏  举报