首页 > 其他分享 >学习记录11面向对象

学习记录11面向对象

时间:2022-09-25 12:01:19浏览次数:60  
标签:11 调用 记录 对象 子类 构造 面向对象 父类 方法

什么是面向对象

面向过程(具体)&面向对象(抽象)

面向过程思想(线性思维)

  • 步骤清晰简单,第一步怎么做,第二部怎么做

  • 面向过程处理一些较为简单的问题
    面对对象思想(分类思维)

  • 物以类聚,分类的思维模式,思考问题首相解决问题需要那些分类(将具有共同特性的方法提取,属性加方法就构成了类),然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索

  • 面向对象是适合理复杂的问题,以及处理需要很多人协作的问题

  • 对于描述复杂的事物,为了从宏观上八五、从整体上合理分析,我们需要使用面向对象的思路,来分析整个系统。但是具体到微观操作,仍需要面向过程的思路去处理,两者不可分割
    面向对象编程(Object-Oriented Programming,OOP)
    面向对象编程的本质就是:以类的方式组织代码,以对象的形式封装数据
    抽象 把公共要素提取出来
    三大特性:

  • 封装

  • 继承

  • 多态
    从认识(了解)的角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象(对象:很多人,很多项目;类:将人中或项目中的公共特性整合,当然,并不是说两者混合)
    从代码运行的角度考虑是想有类再有对象。类是对象的模板。
    用一个类创建出一个对象,那么这个对象就是在这个类名下的,那么这个类里的数据及方法,就可以被这个对象用“.”操作符调用,换句话说,只要这个对象是这个类的,那么这个类里的数据就是这个对象的

方法回顾和加深

方法的定义

修饰符 返回值类型 方法名(……){
       //方法体
       return 返回值;
}

修饰符

  • 修饰符用public

返回类型

  • 依据需求设定,在修饰符后

break 和 return 的区别

  • break:跳出switch,结束循环
  • return:返回值与返回值类型必须相同。结束方法,返回一个结果,其以下的语句不再执行

方法名

  • 注意规范,见名知意。类:小驼峰;方法:小驼峰;常量:大写;变量:小驼峰

参数列表

(参数类型,参数名)…相当于数组

异常抛出

(后面细学)

方法的调用:递归

静态方法

  • 静态方法 static。在另一个类创建了一个方法,用static修饰过后,可以在别的类中调用这个方法,在Demo01中创建了一个say方法,我们现在在Demo02中调用,如下


    调用方法就是“类名.方法()”
    静态方法和类一起加载,当类存在时,该方法就存在;但非静态适当类被实例化时才有效
    当两个方法同为静态或非静态时,可以互相调用

非静态方法

  • 非静态方法 不用static修饰。把Demo01中say方法的static去掉,则就无法在Demo02中调用say方法,报错

    那么如何解决呢(仍想调用Demo01中的say)?将调用目标所在的类实例化,即是用new关键字修饰类,操作如下


    调用方法就是“new 类名.方法()”
    或者


    调用方法就是“对象类型(写目标类的名)+对象名(自定义) = 对象值(new 类名())

形参和实参

  • 形参:在方法中填写的参数,没有具体的值,是占位符,该参数用于要求实参的数据类型,而系统也会依据实参的数据类型来自动选择所调用的方法,因此,在设定形参时一定要表明数据类型
  • 实参:是在实际使用过程中传递的参数,传递时要依据形参的数据类型传递相应的数据

值传递和引用传递(导致两者结果的不同,是在各自的操作机制中,所操作的值是不同的)

值传递

  • 调用方法change时,main方法只是把实参的值传递给了形参,而由于change方法返回值为空,最终并未把改变的值传回来,也就没有再给原来的实参赋新的值。也就是说,调用方法之后,方法所改变的值是形参的值,在这种情况下想要在去改变实参,就必须把形参值赋给实参

引用传递


  • 调用change方法时,把这个对象传进去,相当于是在把age类传进去。而传进去之后的具体操作,以及操作那些值,可通过方法体看出,从方法体可以看出,,当对象被传进来之后,具体的操作是“改变”,具体的操作数值是age当中的num
    这时候,我们再来看两者的输出结果。

    值传递:程序要输出的结果是实际参数,而方法所改变的是形参的值,实参没有被改变,所以输出的值没有变;
    引用传递:程序要输出的结果是实际参数,实际参数来源于新定义的类中,那么换句话说,程序要输出的结果是新定义的类中的参数,而方法所改变的正是类中的参数值,所以输出的值被改变了

this关键字

代指当前这个类的某个数据(this.name),或当前参数

对象的创建分析

类与对象的关系
类是一种抽象的数据类型,它是对某一类事务整体的描述/定义,但是并不代表某一个具体的事物
类中只有当两个东西:

  • 1.静态的属性:属性
  • 2.动态的方法:方法
    动物:动物有很多种;植物:植物也有很多种;这里的“动物”“植物”就是类
    对象是抽象概念的具体实例
    狗,就是动物这个类的具体实例
    能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念

创建于初始化

创建

使用new关键字创建对象

  • 创建类之后,最好不要在内部加上main方法,类就应该是一个单纯的类。一个项目应该只存在一个main方法。换句话说就是和之前学的C++一样,把类和主方法分开,测试时在主方法里调用就行,如下

初始化

  • 使用new关键字创建对象时,除了分配内存空间之外,还会给创建好的对象进行默认的初始化,以及对类中构造器的调用
    类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
  • 必须和类的名字相同
  • 必须没有返回类型,也不能写void
    构造器必须要掌握

构造器详解

  • 一个类即使里面什么都不写,也会默认存在一个方法。这是系统默认的(隐式),这就是构造器
public Person(){
    //空
}

默认的值也是null
Person person = new Person();这样的形式,本质是调用构造器,构造器本质是一种方法

显式构造器

  • 显式构造器可以是空的,也可以不为空,但必须符合构造器的定义要求,内部的属性可以自行定义,定义过后,便成为系统默认初始化的值,应用在一些游戏当中,或者恢复出厂化设置

有参构造器

  • 有参构造,是当调用方法时传递了参数,而实现了上述作用,即,类内部的属性可以自行定义,定义过后,只要传参,一部分数据就根据有参构造器所设定的内容被初始化
    有了有参构造器之后,无参构造器必须显式构造
    我们经常采用Person person = new Person()这样的形式去调用构造器,这是一种无参状态下调用构造器,这样的形式就要求了必须存在无参构造器,所以,当有参构造器存在时,我们必须构造无参构造器

*总结:
1.默认构造器是系统构造的,内容为空。
2.显式无参构造器,自定义,内容可以为空,可以不为空。
3.构造了有参构造器之后,必须构造一个显式无参构造器。
4.使用new操作符创建对象,必须存在显式无参构造器。
5.构造器的作用,就是用于初始化,可分为无参状态时的初始化,和有参状态时的初始化,可以根据这个特点,设置bug玩。

JAVA的三大特性

封装

  • 该露的露,该藏的藏
    程序设计追求“高内聚,低耦合”,高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合,就是只暴露少量的方法给外部使用。比如电视,电线都封装在内部,只留了开关等一些简单的操作与接口在外
  • 封装(数据的隐藏)
    通常,禁止直接访问一个对象中数据的实际表示,二通过操作接口来访问,这称为信息隐藏

属性私有,get/set。private,与public相对应,修饰修饰属性,当属性被定义为private时,无法在主程序中访问,方法同理

要提供一些可以访问的方法,就是public的get、set方法
get:获取这个数据
set:给这个数据赋值

换句话说就是,外部不能访问其私有属性,那就在类内部创建get/set方法,通过对象在外部调用get/set的方法,进而实现在外部访问自己的属性
由于方法是封装的,我们可以在set方法内部进行安全性检查,其实就是在方法内设定一些条件,可以通过if条件句来实现

封装的意义:

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

继承

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

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

  • JAVA中类只有单继承,没有多继承!(一个父类可有多个子类,而一个子类只能有一个父类)

  • 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
    继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。子类和父类之间,从意义上讲应该具有"is a”的关系

  • 被final修饰的类,不能够被继承

    可以看到,Person类中有方法say,Students中没有,但却可以在主方法中调用say方法

  • 子类可以继承父类的所有属性和方法,前提是public修饰。不过,根据封装的思想,一般是将属性设定为private,所以,要通过get/set方法访问

  • 在JAVA中,所有的类都默认继承Object类,也都可以使用其中包含的方法。

  • “ctrl+h”可以查看所有子类与父类的继承关系

  • Object类
    在JAVA中,所有的类都默认继承Object类,也都可以使用其中包含的方法

super关键字 子类调用父类

子类调用父类,前提是调用的目标是public

默认super关键字 主函数中调用子类的无参构造器,也会同时调用父类的无参构造器,默认调用父类构造器的过程在子类的构造器中完成,这样的过程是系统默认的。默认隐藏的代码是:super()
而且,当在某些情况下,需要显式构造无参构造器时(默认代码与显示代码都是在子类构造器之中的),super()、this()代码必须写在构造器代码体的首行,但两者不能同时出现,super()也可以用于调用父类有参构造器,规则一样
通过前面对构造器的学习,我们知道,当构建了有参构造器后,我们必须构造显式无参构造器,这些知识与规则都是相通的

可以看见,主函数调用子类的有参构造器时,依旧调用了父类的无参构造器


可以看见,当子类中无参构造器被注释掉以后,右侧调用子类无参构造器的代码报错
super注意点:

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

this VS super

  • 代表的对象不同:
    this: 当前对象调用自身
    super: 代表父类对象的引用
  • 前提
    this:不是继承状态就可以使用
    super:只能在继承状态下才可以使用
  • 构造方法
    this():本类的构造
    super():父类的构造

都是调用本类或者父类的其他方法,只不过要遵守一些原则

方法重写

重写都是方法的重写,和属性无关
当方法是静态static时,方法的调用之只和等号的左边有关,即,引用类型(是父类?是子类?)

所以,只有当非静态时,才能方法重写。也就是说,重写只和非静态有关
当方法是非静态时,方法的调用和等号右边有关,即,实例类型

方法重写条件:

  • 1.方法名必须相同
    2.参数列表必须相同,否则就变成了重载
    3.修饰符,范围(子类的范围)可以扩大但不能缩小,方法的关键字必须是public.public>protect>default>private
    4.方法必须是非静态
    5.重写可能抛出异常,范围可以被缩小,不能被扩大
    6.重写,子类的方法名和父类必须要一致,方法体不同

为什么需要重写

  • 父类的功能子类不一定需要或无法满足子类
    注意:子类重写了父类的方法,当实际类型是子类的对象(无论引用类型是谁),都执行子类的方法。
    引用类型是父类,那么在调用时,同一个方法,子父类都有的话,调用子类的;只有父类有的话,调用父类的
    子类引用类型,可以调用自身、共有以及继承父类的方法
    父类引用类型,可以调用自身或与子类共有的,但不能调用子类独有的方法

多态

动态编译:类型:可扩展性
在实例类型确定的情况下,同一方法可以引用类型的不同而采用多种不同的行为方式(存在一定的规则)。一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多

规则:

  • 引用类型是父类,那么在调用时,同一个方法,子父类都有的话,调用子类的;只有父类有的话,调用父类的
  • 子类引用类型,可以调用自身、共有以及继承父类的方法
  • 父类引用类型,可以调用自身或与子类共有的,但不能调用子类独有的方法

多态存在的条件

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

注意:
1.多态是方法的多态,属性没有多态性。方法重写也是
2.有父类和子类这样一种联系,才能用多态 否则报错:类型转换异常 ClassCastException!
3.多态存在的必要条件:

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

不能够被重写的方法

  • 1.static方法,属于类,不属于实例
  • 2.final修饰的
  • 3.private私有的

instanceof类型转换:强制转换,自动转换(引用类型之间的转换)

  • instanceof用于判断一个对象是什么类型
    公式:System.out.println(X instanceof Y)能不能编译通过,取决于对象X与类Y之间是否存在父子的正向或反向的关系;同级或者两者没有关系,则编译阶段就会报错
    一个对象,用父类引用那它就是父类类型,用子类引用就是子类类型,但这个对象的拥有者,必须是等号右边的类,如:Person person = new Students(),person是Person类型,是Students的对象
    instanceof返回结果判定:比如,存在父子关系A>B>C,c是C的对象,可称为,c是B子类的对象、c是A子子类的对象,这样的情况,返回结果为true;反之为false
    编译通过后会把a和B比较,如果a是B本类或者子类的对象,结果就是true,反之就是flase。所以根据以上规则得到如下结果:

强制转换
由高到低

自行转换
由低到高,子类转化为父类有可能丢失一些方法


注意:
1.父类的引用指向子类的对象
2.子类转父类向上转型,自由转换
3.父类转化成子类,强制转换(可能会丢失方法)
4.为了方便方法调用,减少重复的代码

static关键字详解


三者的输出顺序:

再写一遍new Person(),观察结果

静态代码块,只执行一次。根据匿名代码块的特性,可以应用于赋初始值。

抽象类

  • abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。

  • 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。(就是只写方法名,没有方法体,并且也需要abstract修饰)

  • 抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。

  • 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。

  • 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。

  • 抽象类里可以有正常方法

  • 抽象类是否有构造器?

  • 抽象类存在的意义?

接口

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有
  • 接口:只有规范(专业抽象,约束和实现分离:面向接口编程)(格式:返回值类型 方法名(参数)并且方法都是public abstract)
  • 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是...则必须能..”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你好人,则必须干掉坏人。接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。
  • OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计 模式都只针对具备了抽象能力的语言(比如c++、java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。
    通过interface来声明,在其实现类中,用implements来实现

    从上面可以看出,接口是多继承的
    在实现类中,必须重写方法

接口的作用

  • 1.约束
  • 2.定义一些方法
  • 3.方法都是public abstract(抽象)
  • 4.常量都是public static final
  • 5.接口不能被实例化(因为内部不存在方法)
  • 6.用implements实现多个接口
  • 7.必须重写接口中的方法

内部类及OOP实战(OO是面向对象)

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

1.成员内部类
Outer.Inner inner = outer.new Inner();“Outer.Inner”代表对象类型,“inner”代表对象名,“outer.new”用外部类对象来new(实例化)Inner(内部类)的对象

一个java类里面只能有一个public class文件,之前学的是在大的java文件中写了两个不同的类,而不是在类中有嵌套了一个类
2.静态内部类
就是将原来的内部类,生命成为静态的
注意:静态的内部类不可以再获得外部的属性或方法,因为静态方法和类是同时加载的,是在属性之前生成的
3.局部内部类
在方法中写个类
4.匿名内部类
没有名字初始化类,不用把实例保存到变量中。就是有这个东西,可以完成相应功能,但没有名字

标签:11,调用,记录,对象,子类,构造,面向对象,父类,方法
From: https://www.cnblogs.com/hezhipeng/p/16716453.html

相关文章

  • 购物车程序的面向对象设计(一)
    一、人员分工1.网络2113202121333063徐彬晶负责商品类、商城类、仓库类、菜单类(普通用户菜单)、参与讨论博客的编写2.网络2113202121333064黄坤负责商品类、购物车......
  • mysql左连接 计算记录数量(mysql多表关联 计算数据条数)
    设计两个表一个是book字段为bookID,bookName,publishName,另一个表为questions主要字段questionid,title,bookid等等,现在的需求设计一条sql语句显示书名、试题名......
  • 011——常用API(String , ArrayList)
    常用API(String,ArrayList)API(ApplicationProgrammingInterface,应用程序编程接口)Java写好的程序(功能),咱们可以直接调用。Oracle也为Java提供的这些功能代码......
  • C# – 11.0
    前言.NET7来到RC阶段了.C#11也伴随而来咯,这篇看看有哪些可能会用上的好功能呗. 参考What'snewinC#11  ......
  • 11、springsecurity
    @GetMapping用于将HTTPGET请求映射到特定处理程序方法的注释。具体来说,@GetMapping是一个作为快捷方式的组合注释@RequestMapping(method=RequestMethod.GET)。......
  • windows11 22H2突破限制成功在线更新升级
    windows11突破限制成功在线更新升级1、C:\$WINDOWS.~BT\Sources\Panther文件Appraiser_Data.ini删除新建同名空文件夹替换(包含后缀)2、C:\$WINDOWS.~BT\Sources\文件Ap......
  • Weekly Contest 311
    WeeklyContest311ProblemASmallestEvenMultiple思路水题,判一下奇偶就行代码classSolution:defsmallestEvenMultiple(self,n:int)->int:if......
  • AGC013 记录
    赛次总结A.SortedArrays题意给定一个长度为\(n\)的数组,可以划分为多少个单调不减或单调不增的数组。【AC】B.HamiltonishPath题意给定一个\(n\)个点\(m\)......
  • git推送报错:你的推送将发布一个私人电子邮件地址解决方案记录
    本地新建分支且已经切换到新分支 使用 gitpush远程库名 分支名  命令推送后报错如下:  重点看红框信息,翻译一下就是你将要发布一个私人邮箱地址,先百度找了......
  • 有意思的面试记录
    碰见一个很有意思的【百度面试】,和我好像hhh链接:https://www.bilibili.com/video/BV18Z4y1T7yZ/【类加载机制】类加载过程:加载+链接+初始化双亲委派--保证程序的稳......