写点什么

Java 面向对象知识点拆分(一)

作者:逆锋起笔
  • 2022 年 3 月 11 日
  • 本文字数:5498 字

    阅读完需:约 18 分钟

Java面向对象知识点拆分(一)

Java 面向对象的编程思想是极其重要的,可以说是 Java 的核心,这块内容比较细,比较多,花了两周时间,整理出来 47 条知识点,帮助大家稳固基础,早日实现年薪百万,哈哈~

1、面向对象

初学者接触最多的一句话就是 Java 是一门面向对象的编程语言,然而能理解的并不多,其实很多问题如果使用面向对象的思想去解答,会特别的合理,还能把很难的问题简单化,但实际开发中很少能做到这一点。下面是几个例子,结合万事万物皆对象的理念多想想,慢慢就会有感觉。


  • 举例 1:将大象装进冰箱

  • 举例 2:叫人买电脑

  • 举例 3:软件公司招技术人才

  • 举例 4:到饭店叫服务员点菜

2、类和对象的关系

类:就是对现实生活中事物的描述。


对象:就是这类事物,实实在在存在的个体。

3、封装

是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。


好处:


  • 将变化隔离;

  • 便于使用;

  • 提高重用性;

  • 提高安全性。


原则:


将不需要对外提供的内容都隐藏起来;把属性都隐藏起来,提供公共方式对其访问。

4、构造函数

作用:可以用于给对象进行初始化。


注意:①当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数。②当在类中定义了构造函数后,默认的构造函数就没有了。③一个对象建立,构造函数只运行一次;而一般的方法可以被该对象调用多次。


构造函数和一般函数在写法上有不同:


在运行上也有不同:


构造函数是在对象一建立就运行,给对象初始化。而一般方法是在对象调用才执行,给对象添加具备的功能。

5、构造代码块

作用:给对象进行初始化。


对象一旦建立就运行,而且优先于构造函数执行。


和构造函数的区别:


​ 构造代码块是给所有对象进行统一初始化;而构造函数是给对应的对象初始化。


构造代码块中定义的是不同对象共性的初始化内容。

6、关键字—static

用法:


是一个修饰符,用于修饰成员(成员变量,成员函数);当成员被静态修饰后,就多了一种调用方式,除了可以被对象调用外,还可以直接被类名调用。类名.静态成员。


特点:


①随着类的加载而加载(随着类的消失而消失


最长)②优先于对象存在(静态先存在,对象后存在)③被所有对象所共享④可以直接被类名所调用。


实例变量和类变量的区别:


​ ①存放位置:类变量随着类的加载而存在于方法区中;实例变量随着对象的建立而存在于堆内存中。②生命周期:类变量生命周期最长,随着类的消失而消失;实例变量生命周期随着对象的消失而消失。


静态使用注意事项:


​ ①静态方法只能访问静态成员;非静态方法既能访问静态也可以访问非静态②静态方法中不可以定义 this,super 关键字。因为静态优先于对象存在。所以静态方法中不可以出现 this。


静态利弊:


利处:对对相对共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。可以直接被类名调用。


弊端:生命周期过长;访问出现局限性(静态虽好,只能访问静态)。

7、解析 java 程序主方法 main()

主函数可以被 jvm 加载调用


主函数的定义:


public:代表着该函数访问权限是最大的。


static: 代表主函数随着类的加载就已经存在了。


void: 主函数没有具体的返回值


main: 不是关键字,但是是一个特殊的单词,可以被 jvm 识别。


(String[] str): 参数类型是一个数组,该数组中的元素是字符串。字符串类型的数组。


jvm 在调用主函数时,传入的是 new String[]


class MainDemo{
public static void main(String[] args){
String[] arr = {"haha", "hehe", "heihei", "xixi"}; MainTest.main(arr); }
}
class MainTest{
public static void main(String[] args){
for(int i = 0; i < args.length; i++){ System.out.println(args[x]); } }
}
复制代码

8、什么时候使用静态

1)什么时候定义静态变量(类变量)?


当对象中出现共享数据时,该数据被静态所修饰。对象中的特有数据要定义成非静态存在于堆内存中。


2)什么时候定义静态函数呢?


当功能内部没有访问到非静态数据(对象的特有数据)时。

9、静态代码块

格式:


{
静态代码中的执行语句
}
复制代码


特点:


随着类的加载而执行,只执行一次,用于给类进行初始化的。

10、对象的初始化过程

Person p = new Person();
复制代码


①因为 new 用到了 Person.class.所以会先找到 Person.class 文件并加载到内存中。②执行该类的 static 代码块,如果有的话,给 Person.class 类进行初始化。③在堆内存中开辟空间,分配内存地址。④在堆内存中建立对象的特有属性。并进行默认初始化。⑤对属性进行显示初始化。⑥对对象进行构造代码块初始化。⑦对对象进行对应的构造函数初始化。将内存地址付给栈内存中的 p 变量。

11、单例设计模式

解决一个类在内存中只存在一个对象。


保证对象唯一及实现方法:


①为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象。【将构造函数私有化】②还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。【在类中创建一个本类对象】③为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。【提供一个方法可以获取到该对象】


定义单例模式时,建议使用饿汉式;因为懒汉式存在安全问题,效率不高。

12、继承

好处:


①提高了代码的复用性;


②让类与类之间产生了关系;正因为有了这个关系,才有了多态的特性。


特性:


java 语言只支持单继承,不支持多继承。因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪一个。但是 java 保留了这种机制,并用另一种体现形式来完成表示。多实现。


java 支持多层继承,也就是一个继承体系。


如何使用一个继承体系中的功能呢?


要想使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。通过了解共性功能,就可以知道该体系的基本功能。那么这个体系已经可以基本使用了。


那么在具体调用时要创建最子类的对象,为什么呢?


①因为有可能父类不能创建对象;②创建子类对象可以使用更多的功能,包括基本的也包括特有的。


总之,查阅父类功能,创建子类对象使用功能。


子父类中变量的特点:


如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用 this;子类要访问父类中的同名变量,用 super。


super 的使用和 this 的使用几乎一致。this 代表的是本类对象的引用。super 代表的是父类对象的引用。


子父类中函数的特点:


当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。这种情况是函数的另一个特性:重写(覆盖)。


当子类继承父类,沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新功能,而是使用覆盖特殊,保留父类的功能定义,并重写功能内容。


覆盖:


①子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。②静态只能覆盖静态。


子父类中的构造函数:


在对子类对象进行构造初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐士的语句 super();super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是 super()。


为什么子类一定要访问父类中的构造函数?


因为父类中的数据子类都可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。


如果要访问父类中指定的构造函数,可以通过手动定义 super 语句的方式来指定。


子类的实例化过程:


结论:


子类的所有的构造函数,默认都会访问父类中空参数的构造函数。因为子类每一个构造函数内的第一行都有一句隐式 super();当父类中没有空参数的构造函数时,子类必须手动通过 super 语句形式来指定要访问父类中的构造函数。当然,子类的构造函数第一行也可以手动指定 this 语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。


注意:


不要为了减少代码量而继承;必须是类与类之间有所关系才可以继承。


重载:只看同名函数的参数列表。


重写:子父类方法要一模一样。(父类中声明为 private 的方法,子类无法实现重写)


super 语句一定定义在子类构造函数的第一行。


方法的重写:


  • 重写方法必须和被重写方法具有相同的方法名、参数列表和返回值类型。

  • 重写方法不能使用比被重写方法更严格的访问权限。

  • 重写和被重写的方法须同时为 static 的,或同时为非 static 的。

  • 子类方法抛出的异常不能大于父类被重写方法的异常。

13、final 关键字

①final 作为一个修饰符,可以修饰类、变量、函数;②被 final 修饰的类不可以被继承;为了避免被继承,被子类复写功能,就将类的修饰符选为 final;③被 final 修饰的方法不可以被复写;④被 final 修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,也可以修饰局部变量;⑤内部内定义在类中的局部位置上时,只能访问该局部被 final 修饰的局部变量。


注意:


当在描述事务时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字,方便于阅读。而这个值不需要改变,所以加上 final 修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成,单词间通过下划线(_)连接。

14、抽象类

定义抽象类:


当多个类中出现相同功能,但是功能主题不同,这时可以进行向上抽取,只抽取功能定义,而不抽取功能主体。


抽象类的特点:


①抽象方法一定在抽象类中;②抽象方法和抽象类都必须被 abstract 关键字修饰;③抽象类不可以实例化对象,因为调用抽象方法没有意义;④抽象类中的抽象方法要被使用,必须由子类复写其所有的抽象方法,建立子类对象调用;如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。


抽象类和一般类没有太大的不同


该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西,这些不确定的部分,也是该事物的功能,需要明确出现,但是无法定义主体,通过抽象方法来表示。


抽象类比一般类多了个抽象函数,就是在类中可以定义抽象方法。抽象类不可以实例化。


特殊:抽象类中可以不定义抽象方法,这样做仅仅是为了不让该类建立对象。

15、模板方法设计模式

定义:在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去。由该类的子类完成.

16、接口

不可以创建对象,因为有抽象方法;需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化,否则子类是一个抽象类。


接口可以被类多实现,也是对多继承不支持的转换形式,java 支持多实现。


接口特点:


  • 接口是对外暴露的规则;

  • 接口是程序的功能扩展;

  • 接口可以用来多实现;

  • 类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口;

  • 接口与接口之间可以有继承关系。

17、多态

可以理解为事物存在的多种体现形态。


多态的 2 种体现:


方法的重载和重写。


对象的多态性——可以直接应用在抽象类和接口上。


父类的引用指向了自己的子类对象;


父类的引用也可以接受自己的子类对象。


多态的前提


必须是类与类之间有关系。要么继承,要么实现;


通常还有一个前提:存在覆盖。


多态的好处


多态的出现大大的提高了程序的扩展性。


多态的弊端


提高了扩展性,但是只能使用父类的引用访问父类中的成员。


多态的应用


在多态中成员函数的特点:


①在编译时期:参阅引用型所属的类中是否有调用的方法。如果有,编译通过;如果没有编译失败。②在运行时期:参阅对象所属的类中是否有调用的方法。


总结:成员函数在多态调用时,编译看左边,运行看右边。


在多态中,成员变量的特点:


无论编译和运行,都参考左边(引用型变量所属的类)。


在多态中,静态成员函数的特点:


无论编译和运行,都参考左边。

18、内部类

内部类的定义规则:


当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事物在使用外部事物的内容。


内部类的访问规则:


①内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式为:外部类名.this。②外部类要访问内部类,必须建立内部类对象。


访问格式:


①当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中,可以直接建立内部类对象。格式:外部类名.内部类名 变量名 = 外部类对象.内部类对象;例如:Outer.Inner in = new Outer().new Inner();②当内部类在成员位置上,就可以被成员修饰符修饰。比如,private:将内部类在外部类中进行封装。static:内部类就具备 static 的特性。当内部类被 static 修饰后,只能直接访问外部类中的 static 成员。出现了访问局限。


在外部其他类中,如何直接访问 static 内部类的非静态成员呢?


new Outer.Inner().function();
复制代码


在外部其他类中,如何直接访问 static 内部类的静态成员呢?


uter.Inner.function();
复制代码


内部类定义在局部时:


①不可以被成员修饰符修饰;②可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部中的变量。只能访问被 final 修饰的局部变量。


注意:当内部类中定义了静态成员,该内部类必须是 static 的。当外部类中的静态方法访问内部类时,内部类也必须是 static 的。


匿名内部类:


①匿名内部类其实就是内部类的简写格式;②定义匿名内部类的前提:内部类必须是继承一个类或者实现接口;③匿名内部类的格式:new 父类或者接口(){定义子类的内容};④其实匿名内部类就是一个匿名子类的对象。可以理解为带内容的对象。

19、关键字—this

this:代表本类对象,哪个对象调用 this 所在函数,this 就代表哪个对象。


以上这部分内容是面向对象这块的核心内容,我们都知道,封装、继承和多态是 Java 面向对象的三大块内容,如果你已经学习了一遍基础知识,那么这个总结是最适合你来温故知新的,也可以用来查缺补漏。下节内容将会介绍 JavaSE 的核心 API 知识,包括集合框架、文件操作、常用类和方法等。

发布于: 刚刚阅读数: 2
用户头像

逆锋起笔

关注

公众号「逆锋起笔」主理人 2018.07.31 加入

程序视角,转射人生!

评论

发布
暂无评论
Java面向对象知识点拆分(一)_面向对象_逆锋起笔_InfoQ写作平台