面向对象
1.面向对象思想
(1)思想的概述:
面向对象是相对于面向过程而言的,面向过程强调的是功能,面向对象强调的是将功能封装进对象,强调具备功能的对象;
(2)面向对象思想的特点:
A:面向对象就是一种常见的思想。符合人们的思考习惯。
B:面向对象的出现,将复杂的问题简单化。
C:面向对象的出现,让曾经在过程中的执行者,变成了对象中的指挥者。
对象:
世间万物皆对象,对象是事物存在的实体。在java中通过new来创建的。
静态特性
对象特有的属性,不能动的部分,用四类八种基本数据类型+string类型保存
动态特性
对象具备的行为,用方法来体现
类
用java语言对现实生活中的事物进行描述,通过类的形式来体现的。
类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体被称为类。类是抽象的
对象是类抽象出来的一个实例
定义类其实就是在定义类中的成员。
成员:成员变量<-->对应于类对象的属性,
成员方法<-->对应于类对象的行为。
对象
对象是一类事物中抽象出来的一个实例
用 new操作符来创建一个对象
使用“对象.类成员”来获取对象的属性和行为
匿名对象:没有名字的对象 ,如 new Car() ,其实就是定义对象的简写格式。
当对象对方法仅进行一次调用的时候,就可以简化成匿名对象
匿名对象可以作为实际参数进行传递
面向对象的特征主要有以下几个方面:
封装(英语:Encapsulation)
封装就是隐藏对象的属性和实现细节,只向外界提供最简单的编程接口,对数据的访问只能通过已定义的接口。封装是面向对象编程的核心思想,将对象的属性和行为绑定起来,而将对象的属性和行为封装起来的载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。
封装的好处:1.将变化隔离;2.方便使用;3.提高复用性;4.提高安全性
封装的优点:1. 良好的封装能够减少耦合。2. 类内部的结构可以*修改。
3. 可以对成员变量进行更精确的控制。4. 隐藏信息,实现细节。
继承
继承:多个类中存在相同的属性和行为时,将这些相同的内容抽取到单独的一个类中,那么多个类就无需再定义这些相同的属性和行为,只需继承那个类即可。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。
继承就是子类继承父类的所有特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
但是父类中private属性在子类中,不能直接访问,我们可以通过父类的公共方法进行调用
通过 extends 关键字可以申明一个类是从另外一个类继承而来的
继承的特点:子类继承了父类的所有属性
多态
一个对象在程序不同运行时刻代表的多种状态,父类或者接口的引用指向子类对象
多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供的服务,那么运行时的多态性可以解释为:当A系统访问B系统提供的服务时,B系统有多种提供服务的方式,但一切对A系统来说都是透明的(就像电动剃须刀是A系统,它的供电系统是B系统,B系统可以使用电池供电或者用交流电,甚至还有可能是太阳能,A系统只会通过B类对象调用供电的方法,但并不知道供电系统的底层实现是什么,究竟通过何种方式获得了动力)。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:1). 方法重写(子类继承父类并重写父类中已有的或抽象的方法);2). 对象造型(用父类型引用引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。
多态时成员的特点:
1,成员变量。
编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败。
运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量。
简单说:编译和运行都参考等号的左边。哦了。
作为了解。
2,成员函数(非静态)。
编译时:参考引用型变量所属的类中的是否有调用的函数。有,编译通过,没有,编译失败。
运行时:参考的是对象所属的类中是否有调用的函数。
简单说:编译看左边,运行看右边。
因为成员函数存在覆盖特性。
3,静态函数。
编译时:参考引用型变量所属的类中的是否有调用的静态方法。
运行时:参考引用型变量所属的类中的是否有调用的静态方法。
简单说,编译和运行都看左边。
其实对于静态方法,是不需要对象的。直接用类名调用即可。
抽象:abstract抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两个方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
抽象方法和抽象类
关键字是abstract,
abstract修饰的方法称为抽象方法
访问控制域 abstract 返回值类型 方法名();抽象方法不能有方法体
abstract修饰的类称为抽象类
可以拥有抽象方法的类叫做抽象类
成员变量和局部变量的区别:
1,作用域
成员变量定义在类中,整个类中都可以访问。
局部变量定义在函数,语句,局部代码块中,只在所属的区域有效。
2,存储位置
成员变量存在于堆内存的对象中。
局部变量存在于栈内存的方法中。
3,生命周期
成员变量随着对象的创建而存在,随着对象的消失而消失。
局部变量随着所属区域的执行而存在,随着所属区域的结束而释放。
4,初始化
成员变量都有默认初始化值。
局部变量没有默认初始化值,使用前必须赋值初始化。
成员方法
返回值类型 方法名(参数列表){ 方法体 }
成员方法分为有参和无参两种,同时还分为有返回值和无返回值
成员方法无返回值可以用“void”关键字表示返回值类型
成员方法有返回值的,返回值类型要与方法返回的值类型一致
成员方法中可以调用其他成员方法和成员变量,但不能创建
成员方法中可以定义一个变量,叫做局部变量,当局部变量和成员变量同名时,方法首先访问的是局部变量
在成员方法内定义的变量称为局部变量
方法中的形参也是一个局部变量
局部变量在方法被执行时创建,在方法执行结束时被销毁
局部变量使用时必须进行赋值操作或被初始化
局部变量的有效范围称为变量的作用域
权限修饰符
public
protected
private
关键字private:
(1)私有的意思,权限修饰符 (2)用来修饰成员变量和成员函数
(3)用private修饰的成员只在本类中有效 (4)私有是封装在代码中的体现
当声明类时不使用权限修饰符时,则系统默认设为protected
类的权限设定会约束成员上的权限设定
构造方法
(1)特点:
构造方法的名称要和对象所在的类的名称相同,唯一一个首字母大写的方法
构造方法没有返回值类型,没有返回值
(2)作用:
构造函数是用于创建对象,并对其进行初始化赋值,对象一建立就自动调用相对应的构造函数,
构造方法一般都是放在new之后调用
(3)构造方法的注意事项:
A:如果一个自定义类没有构造方法,系统会默认给出一个公共的、无参数的、空的构造方法。
B:如果一个自定义类提供了构造方法,那么,系统将不再给出无参构造方法。这个时候,你可以不使用无参构造方法。如果你想使用,那么,就必须手动给出无参构造方法。
建议:一般情况下,我们的自定义类都要手动给出无参构造方法。
子父类的构造函数:子类创建时必须先调用父类的构造方法
(4)构造方法和成员方法的区别
A:格式区别
构造方法和类名相同,并且没有返回类型,也没有返回值。
普通成员方法可以任意起名,必须有返回类型,可以没有返回值。
B:作用区别
构造方法用于创建对象,并进行初始化值。
普通成员方法是用于完成特定功能的。
C:调用区别
构造方法是在创建对象时被调用的,一个对象建立,只调用一次相应构造函数
普通成员方法是由创建好的对象调用,可以调用多次
构造代码块:
(1)作用:给对象进行初始化,对象一建立就执行,而且优先于构造函数执行
(2)构造代码块和构造函数的区别:
构造代码块是给所有不同对象的共性进行统一初始化
构造函数是给对应的对象进行初始化
this关键字
(1)this关键字代表本类对象的一个引用,谁调用this所在的方法,this就代表谁
(2)this的使用场景
A:用于区分同名成员变量和局部变量;可以使用“this.成员变量名”这样的格式来引用成员变量名
B:在定义函数时,该函数内部要用到调用该函数的对象时,因为此时对象还没建立,故this代表此对象
B:构造函数间调用this 关键字引用其它的构造方法的时候,this(参数)必须作为第一条语句存在。
Person p = new Person();
在内存中做了哪些事情;
(1)JVM读取指定路径下的Person.class文件,并加载进内存中,
如果有直接的父类的情况下,会先加载Person的父类
(2)如果p定义在主方法中,那么,就会在栈空间开辟一个变量空间p。
(3)在堆内存给对象开辟空间、并分配地址。
(4)在对象开辟好的空间中,对对象中的属性进行默认初始化。
(5)对对象中的成员进行显示初始化。
(6)调用构造代码块对对象进行初始化。(如果没有就不执行)
(7)调用构造方法对对象进行初始化。
在构造函数中,第一行会先调用父类中的构造函数进行初始化。(如果没有就不执行)
父类初始化完毕后,在对子类的属性进行显示初始化。
在进行子类构造函数的特定初始化;
对象初始化完毕。
(8)将对象的内存地址赋值给引用变量p,让p变量指向该对象。
子父类中的构造函数的特点
1.在子类构造对象时,发现,访问子类构造函数时,父类也运行了,为什么呢?
原因是:在子类的构造函数中第一行有一个默认的隐式语句。 super();
子类的实例化过程:子类中所有的构造函数默认都会访问父类中的空参数的构造函数。
2.为什么子类实例化的时候要访问父类中的构造函数呢?
那是因为子类继承了父类,获取到了父类中内容(属性),所以在使用父类内容之前,
要先看父类是如何对自己的内容进行初始化的。所以子类在构造对象时,必须访问父类中的构造函数。
3.为什么完成这个必须的动作,就在子类的构造函数中加入了super()语句。
如果父类中没有定义空参数构造函数,那么子类的构造函数必须用super明确要调用
父类中哪个构造函数。同时子类构造函数中如果使用this调用了本类构造函数时,
那么super就没有了,因为super和this都只能定义第一行。所以只能有一个。
但是可以保证的是,子类中肯定会有其他的构造函数访问父类的构造函数。
注意:supre语句必须要定义在子类构造函数的第一行。因为父类的初始化动作要先完成。
static关键字:
(1)静态的意思,用来修饰成员变量和成员函数
(2)静态的特点:随着类的加载而加载,优先于对象存在,对所有对象共享,可以被类名直接调用(3)静态的注意事项
A:静态方法只能访问静态成员为什么:因为静态的内容是随着类的加载而加载,它是先进内存的。
B:静态方法中不能使用this,super关键字
C:不能将方法体内部的局部变量声明为static
D:主方法是静态的,静态方法中不可以直接调用非静态方法
public static void main(String[] args)
public:公共的意思,是最大权限修饰符。
static:由于jvm调用main方法的时候,没有创建对象。只能通过类名调用。所以,main必须用static修饰。
void:由于main方法是被jvm调用,不需要返回值。用void修饰。
main:main是主要的意思,所以jvm采用了这个名字。是程序的入口。
String[]:字符串数组args:数组名
静态的优点和弊端
优点:对对象的共享数据进行单独空间的存储,节省内存,没有必要每个对象都存储一份可直接被类名调用
弊端:生命周期过长,随着类的消失而消失访问出现权限,即静态虽好但只能访问静态
(6)什么使用使用静态呢?
A:当所有对象共享某个数据的时候,就把这个成员变量定义为静态修饰的。
B:当某个方法没有访问该类中的非静态成员,就可以把这个方法定义为静态修饰。
静态的生命周期比较长,所以一般不推荐使用。
由 static 修饰的变量、常量、方法被称为静态变量、常量、方法,统称为静态成员
静态成员是属于类所有的,可以在本类或其他类使用“类名.静态成员名”调用静态成员
静态变量和成员变量的区别
A:调用方式
静态变量也称为类变量,可以直接通过类名调用。也可以通过对象名调用。
这个变量属于类。
成员变量也称为实例变量,只能通过对象名调用。这个变量属于对象。
B:存储位置
静态变量存储在方法区长中的静态区。
成员变量存储在堆内存。
C:生命周期
静态变量随着类的加载而存在,随着类的消失而消失。生命周期长。
成员变量随着对象的创建而存在,随着对象的消失而消失。
D:与对象的相关性
静态变量是所有对象共享的数据。
成员变量是每个对象所特有的数据。
静态代码块
被static修饰的代码块称为静态代码块
A:它只执行一次,它比main还先执行。
B:执行顺序:静态代码块--构造代码块--构造方法
重载(Overload)和重写(Override)
方法的重载和重写都是实ava多态性的不同表现,重载可以理解成多态的具体表现形式,重写是父类与子类之间多态性的一种表现,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
重载(Overload)
重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
重载规则
- 被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 重载对返回类型没有特殊的要求,无法以返回值类型作为重载函数的区分标准。
重写(Override)
重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的方法名、相同的返回类型,参数列表中,参数的个数、顺序、类型必须一样,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。
使用被重写的方法时,该方法满足就近调用的原则
本类中有该方法的定义,则直接调用,没有
方法的重写规则
- 参数列表必须完全与被重写方法的相同;
- 返回类型必须完全与被重写方法的返回类型相同;
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
- 父类的成员方法只能被它的子类重写。
- 声明为final的方法不能被重写。
- 声明为static的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个方法,则不能重写这个方法。