平均分格
879
2022-05-30
Java面向对象的编程思想是极其重要的,可以说是Java的核心,这块内容比较细,比较多,花了两周时间,整理出来 47 条知识点,帮助大家稳固基础,早日实现年薪百万,哈哈~
初学者接触最多的一句话就是Java是一门面向对象的编程语言,然而能理解的并不多,其实很多问题如果使用面向对象的思想去解答,会特别的合理,还能把很难的问题简单化,但实际开发中很少能做到这一点。下面是几个例子,结合万事万物皆对象的理念多想想,慢慢就会有感觉。
举例1:将大象装进冰箱
举例2:叫人买电脑
举例3:软件公司招技术人才
举例4:到饭店叫服务员点菜
类:就是对现实生活中事物的描述。
对象:就是这类事物,实实在在存在的个体。
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:
将变化隔离;
便于使用;
提高重用性;
提高安全性。
原则:
将不需要对外提供的内容都隐藏起来;把属性都隐藏起来,提供公共方式对其访问。
作用:可以用于给对象进行初始化。
注意:①当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数。②当在类中定义了构造函数后,默认的构造函数就没有了。③一个对象建立,构造函数只运行一次;而一般的方法可以被该对象调用多次。
构造函数和一般函数在写法上有不同:
在运行上也有不同:
构造函数是在对象一建立就运行,给对象初始化。而一般方法是在对象调用才执行,给对象添加具备的功能。
作用:给对象进行初始化。
对象一旦建立就运行,而且优先于构造函数执行。
和构造函数的区别:
构造代码块是给所有对象进行统一初始化;而构造函数是给对应的对象初始化。
构造代码块中定义的是不同对象共性的初始化内容。
用法:
是一个修饰符,用于修饰成员(成员变量,成员函数);当成员被静态修饰后,就多了一种调用方式,除了可以被对象调用外,还可以直接被类名调用。类名.静态成员。
特点:
①随着类的加载而加载(随着类的消失而消失
最长)②优先于对象存在(静态先存在,对象后存在)③被所有对象所共享④可以直接被类名所调用。
实例变量和类变量的区别:
①存放位置:类变量随着类的加载而存在于方法区中;实例变量随着对象的建立而存在于堆内存中。②生命周期:类变量生命周期最长,随着类的消失而消失;实例变量生命周期随着对象的消失而消失。
静态使用注意事项:
①静态方法只能访问静态成员;非静态方法既能访问静态也可以访问非静态②静态方法中不可以定义this,super关键字。因为静态优先于对象存在。所以静态方法中不可以出现this。
静态利弊:
利处:对对相对共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。可以直接被类名调用。
弊端:生命周期过长;访问出现局限性(静态虽好,只能访问静态)。
主函数可以被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]); } } }
1)什么时候定义静态变量(类变量)?
当对象中出现共享数据时,该数据被静态所修饰。对象中的特有数据要定义成非静态存在于堆内存中。
2)什么时候定义静态函数呢?
当功能内部没有访问到非静态数据(对象的特有数据)时。
格式:
{ 静态代码中的执行语句 }
特点:
随着类的加载而执行,只执行一次,用于给类进行初始化的。
Person p = new Person();
①因为new用到了Person.class.所以会先找到Person.class文件并加载到内存中。②执行该类的static代码块,如果有的话,给Person.class类进行初始化。③在堆内存中开辟空间,分配内存地址。④在堆内存中建立对象的特有属性。并进行默认初始化。⑤对属性进行显示初始化。⑥对对象进行构造代码块初始化。⑦对对象进行对应的构造函数初始化。将内存地址付给栈内存中的p变量。
解决一个类在内存中只存在一个对象。
保证对象唯一及实现方法:
①为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象。【将构造函数私有化】②还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。【在类中创建一个本类对象】③为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。【提供一个方法可以获取到该对象】
定义单例模式时,建议使用饿汉式;因为懒汉式存在安全问题,效率不高。
好处:
①提高了代码的复用性;
②让类与类之间产生了关系;正因为有了这个关系,才有了多态的特性。
特性:
java语言只支持单继承,不支持多继承。因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪一个。但是java保留了这种机制,并用另一种体现形式来完成表示。多实现。
java支持多层继承,也就是一个继承体系。
如何使用一个继承体系中的功能呢?
要想使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。通过了解共性功能,就可以知道该体系的基本功能。那么这个体系已经可以基本使用了。
那么在具体调用时要创建最子类的对象,为什么呢?
①因为有可能父类不能创建对象;②创建子类对象可以使用更多的功能,包括基本的也包括特有的。
总之,查阅父类功能,创建子类对象使用功能。
子父类中变量的特点:
如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this;子类要访问父类中的同名变量,用super。
super的使用和this的使用几乎一致。this代表的是本类对象的引用。super代表的是父类对象的引用。
子父类中函数的特点:
当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。这种情况是函数的另一个特性:重写(覆盖)。
当子类继承父类,沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新功能,而是使用覆盖特殊,保留父类的功能定义,并重写功能内容。
覆盖:
①子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。②静态只能覆盖静态。
子父类中的构造函数:
在对子类对象进行构造初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐士的语句super();super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super()。
为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类都可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
子类的实例化过程:
结论:
子类的所有的构造函数,默认都会访问父类中空参数的构造函数。因为子类每一个构造函数内的第一行都有一句隐式super();当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。
注意:
不要为了减少代码量而继承;必须是类与类之间有所关系才可以继承。
重载:只看同名函数的参数列表。
重写:子父类方法要一模一样。(父类中声明为private的方法,子类无法实现重写)
super语句一定定义在子类构造函数的第一行。
方法的重写:
重写方法必须和被重写方法具有相同的方法名、参数列表和返回值类型。
重写方法不能使用比被重写方法更严格的访问权限。
重写和被重写的方法须同时为static的,或同时为非static的。
子类方法抛出的异常不能大于父类被重写方法的异常。
①final作为一个修饰符,可以修饰类、变量、函数;②被final修饰的类不可以被继承;为了避免被继承,被子类复写功能,就将类的修饰符选为final;③被final修饰的方法不可以被复写;④被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,也可以修饰局部变量;⑤内部内定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
注意:
当在描述事务时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字,方便于阅读。而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成,单词间通过下划线(_)连接。
定义抽象类:
当多个类中出现相同功能,但是功能主题不同,这时可以进行向上抽取,只抽取功能定义,而不抽取功能主体。
抽象类的特点:
①抽象方法一定在抽象类中;②抽象方法和抽象类都必须被abstract关键字修饰;③抽象类不可以实例化对象,因为调用抽象方法没有意义;④抽象类中的抽象方法要被使用,必须由子类复写其所有的抽象方法,建立子类对象调用;如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
抽象类和一般类没有太大的不同
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西,这些不确定的部分,也是该事物的功能,需要明确出现,但是无法定义主体,通过抽象方法来表示。
抽象类比一般类多了个抽象函数,就是在类中可以定义抽象方法。抽象类不可以实例化。
特殊:抽象类中可以不定义抽象方法,这样做仅仅是为了不让该类建立对象。
定义:在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去。由该类的子类完成.
不可以创建对象,因为有抽象方法;需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化,否则子类是一个抽象类。
接口可以被类多实现,也是对多继承不支持的转换形式,java支持多实现。
接口特点:
接口是对外暴露的规则;
接口是程序的功能扩展;
接口可以用来多实现;
类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口;
接口与接口之间可以有继承关系。
可以理解为事物存在的多种体现形态。
多态的2种体现:
方法的重载和重写。
对象的多态性——可以直接应用在抽象类和接口上。
父类的引用指向了自己的子类对象;
父类的引用也可以接受自己的子类对象。
多态的前提
必须是类与类之间有关系。要么继承,要么实现;
通常还有一个前提:存在覆盖。
多态的好处
多态的出现大大的提高了程序的扩展性。
多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
多态的应用
在多态中成员函数的特点:
①在编译时期:参阅引用型所属的类中是否有调用的方法。如果有,编译通过;如果没有编译失败。②在运行时期:参阅对象所属的类中是否有调用的方法。
总结:成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。
在多态中,静态成员函数的特点:
无论编译和运行,都参考左边。
内部类的定义规则:
当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事物在使用外部事物的内容。
内部类的访问规则:
①内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式为:外部类名.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 父类或者接口(){定义子类的内容};④其实匿名内部类就是一个匿名子类的对象。可以理解为带内容的对象。
this:代表本类对象,哪个对象调用this所在函数,this就代表哪个对象。
以上这部分内容是面向对象这块的核心内容,我们都知道,封装、继承和多态是Java面向对象的三大块内容,如果你已经学习了一遍基础知识,那么这个总结是最适合你来温故知新的,也可以用来查缺补漏。下节内容将会介绍 JavaSE 的核心API知识,包括集合框架、文件操作、常用类和方法等。
Java 面向对象编程
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。