JAVA学习第五天之对象与类

学习目的

  1. 掌握什么是面向对象
  2. 精通java为什么是面向对象的
  3. 掌握类和对象的概念及关系
  4. 掌握面向对象的三大特性
  5. 掌握一个"完整"类的组成
  6. 掌握常用关键字

一.面向对象

  1. 概念
    世间万物,一切事物皆对象。所有的现实物质都可以成为对象,现实中的所有行为都由对象来执行完成。
  2. 定义
    面向对象全称Object Oriented,是一种以对象为中心的编程思想。一切事情由对象去创建、执行和处理。
  3. Java与面向对象
    Java 是一门简单的、面向对象、分布式、解释性、健壮、安全、结构中立、便捷、高性能、多线程、动态的语言。
    如果可以将问题从事物表象中抽取出来,那么什么样的对象可以解决问题呢?这个对象用java代码怎么表示呢?
  4. 作用
    面向对象可以有效提高编程效率,通过封装技术,将对象作为程序的基本单元,将程序和数据封装其中,提高软件的重用性、灵活性和扩展性。
  5. 过程分类
  • OOA:面向对象分析(Object-Oriented Analysis),按照面向对象的思想来分析业务,如何将问题从事物表象中抽取出来。
  • OOD:面向对象设计(Object-Oriented Design),什么样的对象可以解决问题,对象之间的联系以及如何解决问题的。
  • OOP:面向对象编程(Object-Oriented Programming),解决问题的对象用java代码怎么表示和实现。

1.1 面向对象与面向过程

  1. 定义
  • 面向过程:考虑的是实际的具体实现,一般是从上往下步步求精,注重完成一件事情的每一个细节。
  • 面向对象:主要是把事物抽象化对象化,对象包括属性与行为。
  1. 区别
  • 面向过程:当程序规模不是很大时,程序流程清楚,模块与函数的方法很好组织,面向过程因此有优势。<蛋炒饭>
  • 面向对象:对于复杂而庞大的系统,将程序规模分为对象和方法即可,每一段程序都由对象执行具体的方法实现。<蛋盖饭>
  1. 不足
  • 面向过程:一步依赖另一步,注重于细节的每一步实现,关联性过于紧密。
  • 面向对象:将事物抽象成对象的过程难以充分体现现实事物,对象的类别很难满足需求,对象间的关系建立也较难。

二.类与对象

类与对象关系图.png

2.1 类

  1. 定义
    类是现实世界当中具有共同特征的事物。将事物在现实中的共同状态和共同行为,进行抽象形成的模板就叫做类。如:水果、蔬菜、汽车等。
  2. 组成
  • 现实组成:类 = 事物状态 + 事物行为
  • 代码组成:类 = 共有属性 + 公共方法

2.2 对象

  1. 定义
    对象是现实世界实际存在的个体事物,对象是类的实例化。对象包括属性与行为。如:苹果、榴莲、西红柿、奔驰等
  2. 代码实现
    引用类型 变量 = new 引用类型();
    对于new 引用类型()这一整块就是一个对象。
  3. 类与对象关系
    类是对象的抽象,对象是类的实例;由类到对象的过程叫对象的实例化,由对象到类的过程叫抽象。
  4. 对象与jvm堆内存


    对象创建与jvm内存分析.png

三.面向对象三大特性

3.1 封装(Encapsulation)

  1. 概念
    现实生活中有很多现实的例子都是封装的。例如手机,电视机,笔记本电脑,照相机,都是外部由一个外壳封装起来,保护内部部件,保证部件是安全的。封装以后,对于使用者来说看不见内部的复杂结构的,也不需要关心内部有多么复杂,只需要操作外壳的按键按钮就可以完成使用。
  2. 特点
    为了保证内部安全,对属性进行私有化;同时为了方便用户使用,再对外提供一个方法作为公开的访问入口。
  3. 好处
    外部程序通过公开入口去访问数据时,可以在入口处设立关卡,一般在set()方法中设置安全访问,进行安全控制,保证对象内部的数据安全。

3.2 继承(Inheritance)

  1. 概念
    封装好的个体类之间,或者接口之间存在的一种关系。继承时,子类继承父类的特征和行为,使得子类对象具有父类的属性,子类从父类继承父类方法,使得子类具有与父类相同的行为。常称遗传特性,是一种is-a关系
  2. 关键字
    extends关键字表示继承,但类与类之间只支持单继承,不支持多继承。
  3. 作用
  • 实现代码复用:子类可以继承父类的属性和方法,还能拥有属于子类自己特有的属性和方法;
  • 多态的基础:无论是面向接口编程的多态,还是面向抽象(类)编程的多态,基础都是继承。
  1. 范围
    除了父类的构造方法外<构造方法名必须和类名相同>,所有的父类属性和方法都可以被子类继承,包括私有的(私有的属性可以继承,但不能在子类中直接访问,需通过父类的get方法间接访问)。
  2. 特殊点
  • 构造方法不能继承:构造方法是每个类都特有的,构造方法名必须和类名相同,因而不能被继承;
  • 所有的类没有显示的继承任何类时,默认继承 Object 类;
  • 子类没有显示继承父类方法时,默认在子类的类体当中第一行使用super()继承父类方法。
  1. 缺点
  • 子类继承了父类之后的耦合度非常高时,会影响扩展性,父类的修改会影响子类的继承使用
  • 能使用组合关系(组合是多个旧类作为一个新类的属性),尽量不使用继承;组合关系中的旧类代码改变时,不影响新类。
  1. 继承的执行顺序
    父类静态代码块 --> 子类静态代码块 --> 父类代码块 --> 父类构造方法 --> 子类代码块 --> 子类构造方法
    继承的执行顺序.png

3.3 多态(Polymorphism)

  1. 前提
    实现多态的前提是,类完成封装形成了独立体,并且类之间或类和接口之间实现了继承关系,满足向上转型(子转父--自动类型转换)和向下转型(父转子,需加instanceof符)
  2. 概念
    多态就是父类型引用 指向 子类型对象,通过父类或者父接口,创建子类型的对象;
  3. 多态实质
    多态的实际上就是一个引用对象在不同阶段,可以指示多种实际类型的现象,从而产生多种形态、多种状态。java程序在执行之前都分为 编译和运行 两个阶段,多态也因此分为编译期的静态绑定和运行期的动态绑定。

3.3.1 多态的分类

  1. 编译时多态
    编译时多态属于静态绑定的多态。在编译期,编译器只看源代码的语法问题,因此编译期只看到父类型引用,从而找到父类型字节码文件,进行父类方法绑定。(常见错误:f.父类型引用调用子类型方法,找不到该方法
  2. 运行时多态
    运行时多态属于动态绑定的多态。在运行期,会在堆内存中创建一个真实的子类型对象,来执行绑定子类型对象的方法;而不是使用编译时的父类型对象执行父类型方法。
  3. instanceof()运算符
    一个父类可以被多个子类同时继承,当父类想要向下调用某一个子类的特定方法时,需要先向下转型判断该父类型引用指向的是具体哪一个子类型。先匹配,再去调用对应的子类特定方法。instanceof()运算符就是用于测试一个对象是否为一个类的实例。
//使用格式:**obj instanceof class**
//其中 obj为一个对象,Class 表示一个类或者一个接口
if ( 父类型引用  instanceof 子类 ) { 
    子类 变量 = (子类)父类型引用;//向下转型
}
  1. 特别注意
  • 在进行任何向下转型之前,都要使用 instanceof 进行判断
  • 编译阶段和具体 new的对象无关
  • 运行阶段看的是底层具体 new的是哪个类型的子对象,运行期new的是"真实对象",调用的是真实对象的相关方法


    多态的理解.png

四.类的组成

  1. 组成
    每一个类都是从现实世界中抽象出来的,因此类具有现实事物的共同状态和行为,在Java中表示分别表示为属性和方法。

4.1 属性

  1. 概念
    属性是现实事物具有共性状态抽取出来的、用代码表示的"抽象共性"。如物体的颜色、形状、大小,人的年龄、性别、身高等。
  2. 分类
  • 静态属性:使用static关键字修饰的属性,属于类级别,和类一样加载时直接加载到方法区内存。
  • 成员属性:又称为对象属性,非static修饰的属性,需要创建类的实例对象后才能调用。
  • 常量:使用final修饰的属性,不可修改,必须初始化。

4.2 构造器

  1. 概念
    构造器就是类中用于 构造的一个器具,直白的讲就是类用于 构造/创造对象的"工具"。构造器的实质是在堆内存创建出一个对象,并且每调用一次构造器,创建出的对象地址都不一样。
  2. 作用
  • 创建对象:构造方法调用可以创建出一个类的实例对象;
  • 初始化对象属性:调用带参构造器完成属性初始化操作;
  • 实例变量赋值:不是在类加载器加载时赋值,实例变量属于对象的范畴,因而是对象创建(调用构造方法过程中)才会进行赋值。
  1. 特点
  • 一个类中可以定义多个构造方法,多个构造方法形成方法重载;
  • 构造方法的返回值类型实际上是当前类,返回一个当前类的类型的对象。
  1. 编写要求
  • 无返回值
  • 构造方法名必须和类名相同
  • 固定格式:public 类名(参数列表){ };
  1. 构造器使用格式


    构造器使用格式.png
  2. 构造器分类
  • 无参构造:不带参数的构造器,若不重写无参构造,创建出来的对象所有属性为空。
  • 带参构造:带参数的构造器,参数一般为类的属性,创建出来的对象会给所有属性赋值。

4.2.1 无参构造<缺省构造器>

  1. 定义
    没有参数的构造器,只能创建对象,并不能初始化对象属性。
  2. 调用实质
    调用无参构造时,会在堆内存开辟一块空间创建一个新的对象,并给实例变量进行赋默认值。
  3. 特点
    系统默认提供,但建议必须手动写上。

4.2.2 带参构造

  1. 定义
    带有参数的构造器,参数列表一般为该类的属性列表,创建对象时并初始化对象的属性。
  2. 调用实质
    调用带参构造器时,会在堆内存中开辟一块空间存储创建出的一个新的对象,并将栈内存中的局部变量<实际参数> 传递给 堆内存中的对象属性,完成对实例变量的初始化赋值。
  3. 特点
    支持重载,可以编写多个不同参数的带参构造器

4.2.3 this关键字

  1. 含义
    this指向的是当前对象。当某个对象需要使用类的实例变量或者实例方法时,由于某个对象后续才创建的,具有不确定性,因而使用this代替当前对象去使用。
  2. 设计原则
  • this遵循"开闭原则",面向扩展开放,对修改关闭;
  • this表示当前对象,用于指向每一个刚刚创建出来的对象;
  • this用于set()方法中或实例方法中,区分实例变量和方法传进的形式参数(局部变量);
  • this()用在构造方法中(一般是无参构造),只能出现在构造方法第一行,表示调用另一个带参构造方法,如:this(构参1,构参2,构参3)。
  1. 特点
  • this本身存在于虚拟机栈的方法栈帧中,每一个方法栈帧可能有多个局部变量,因此栈帧使用数组保存多个局部变量,而下标0就是this变量;
  • this 不能使用在 static方法中,可以使用在实例方法中;
  • 在实例方法中可以直接访问 this当前对象的实例变量以及实例方法,在 static 方法中无法直接访问 this的实例变量和实例方法。

4.2.4 super关键字

  1. super实质
    super关键字类似于this关键字,this指向的是当前调用的对象,而super指向的是当前子类 所继承的父类对象的部分特征。super代表的只是"this当前对象"父类的一部分特征。并不指向独立的对象,也不保存某个对象的内存地址。
  2. 作用
    super是在子类需要调用父类的构造方法 或者 子类需要对父类的属性和方法进行初始化时使用。
  3. 使用格式
  • super()特指子类调用父类的构造方法,表示 继承父类和子类共同一部分的属性(子类特有的属性可以用this.区分),提高代码复用性;
  • super.属性/方法 特指在子类中调用了父类同名的属性或方法,以便区分 子类和父类的属性或方法;
  • super和this一样无法使用在静态方法当中。
  1. 特点
  • super() 必须是子类构造器中的第一个语句;
  • super()调用父类构造方法 和 this()调用本类构造方法时,在子类构造方法中都只能放在第一行,但是两者不能同时共存,只能写其一;
  • 没有手动写上super()时,系统默认在子类构造方法第一行调用super();
  • super()的默认构造器中没有使用this进行属性赋值,系统会赋默认值。
  1. native关键字
    用native关键字修饰,且以分号结束的方法,表明该方法底层调用的是c++编写的dll程序(dll是动态链接库文件),可以直接在计算机底层运行,不需要重写。

4.3 get()与set()方法

  1. 概念
    get() 与 set()方法是基于类的封装上提供的方法,由于封装性,类的消费者不能对创建类进行直接访问,更不能修改。因此提供get()和set()方法供类的消费者来使用该类。

4.3.1 get()方法

  1. 定义
    用于获取对象属性值的方法,属性private封装私有化后,get()方法提供给外界可以获取该对象的实例变量值。构建类时必须对属性封装和提供get()方法。
  2. 使用格式
//返回值是获取的属性 对应的数据类型值
public 数据类型 get属性名(){ };

4.3.2 set()方法

  1. 定义
    属性使用private封装私有化后,set()方法提供给外界可以修改该对象的实例变量值,专门用于提供给调用者 可以设置、修改、赋值对象属性的方法。
  2. 使用格式
//设置对象的属性值
public void set属性名(){  };

4.4 重写Object类的方法

  1. 概念
    Object类是所有类的父类,系统默认所有类继承于Object,因此也继承了它的所有方法。但是由于Object只是个模板,并未根据现实中具体的需求对具体行为做出响应,因此需要将继承过来的方法进行重写,满足现实需求。
  • toString()方法:重写toString()方法,返回的是以"易读性字符串"来表示该对象;未重写时返回的是 该对象的类型@哈希码经过转换的16进制码值
  • hashCode()方法:未重写时返回的是该对象在内存中的哈希码值,重写后返回的是哈希码值经过哈希算法--转换得到的--对象在内存的下标。
  • equals()方法:未重写时,底层采用==号比较数值;重写后可以比较对象的每一个属性是否相等,从而判断两个对象是否相等。

参考

java多态的实现原理(JVM调用过程)

常见面试题

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容