Java面向对象
1.面向对象思想
《Java编程思想》中提到“万物皆为对象”的概念。它将对象视为一种奇特的变量,它除了可以存储数据之外还可以对它自身进行操作。它能够直接反映现实生活中的事物,例如人、车、小鸟等,将其表示为程序中的对象。每个对象都具有各自的状态特征(也可以称为属性)及行为特征(方法),java就是通过对象之间行为的交互来解决问题的。
面向对象就是把构成问题的事物分解成一个个对象,建立对象不是为了实现一个步骤,而是为了描述某个事物在解决问题中的行为。
类是面向对象中的一个很重要的概念,因为类是很多个具有相同属性和行为特征的对象所抽象出来的,对象是类的一个实例。
类具有三个特性:封装、继承和多态。
封装:核心思想就是“隐藏细节”、“数据安全”,将对象不需要让外界访问的成员变量和方法私有化,只提供符合开发者意愿的公有方法来访问这些数据和逻辑,保证了数据的安全和程序的稳定。
继承:子类可以继承父类的属性和方法,并对其进行拓展。
多态:同一种类型的对象执行同一个方法时可以表现出不同的行为特征。通过继承的上下转型、接口的回调以及方法的重写和重载可以实现多态。
2.类与对象
面向对象中, 万物皆对象,
对象: 生活中,看得见,摸得着的具有的东西都是对象, 具体的
类: 一组相同的特征的对象的集合, 抽象的对象
类与对象的关系:
对象是类的实例化(具体化)
类是对象的抽象出来
类是模板, 对象通过这个模板创建出来的,
使用的对象,不是使用类
总结:总结:类是抽象的,对象是具体的
2.1类的定义
类可以将数据和函数封装在一起,其中数据表示类的属性,函数表示类的行为。定义类就是要定义类的属性与行为(方法)。
public class Person{
int age;
public void say(){
System.out.println("天啊,我的年齡是:" + age);
}
}
,定义了一个Person 类,该类有一个属性age,一个方法say。say方法可以访问age的属性.
2.2属性
对对象的名词性的描述, 静态的描述, 用于存储对象的相关的数据
同一个类创建的对象, 具有相同的属性,这些属性初始值一样,
但是,每个对象的属性的值都可以不一样,
每个对象都是一个独立的个体
属性是有初始值的,特别注意我们前面讲变量的时候,说我们的局部变量在定义的时候是没有初始值的,需要我们手动赋初始值的.这是局部变量与属性的区别.
成员变量 | 类型初始值 |
---|---|
Byte | 0 |
Short | 0 |
Int | 0 |
long | 0L |
float | 0.0F |
double | 0.0D |
char | \u0000(表示为空) |
boolean | false |
String,其他类类型 | Null |
默认初始化——显式初始化——构造器中初始化——对象.属性方式赋值——代码块
2.3方法
对对象的动态的描述, 就是动词性的描述, 表示这个对象拥有什么行为或者什么功能
方法的概念: 一堆代码的集合, 方法是一段具有独立功能的代码块,不调用就不执行。
语法说明:**
1)访问修饰符也就是前面讲属性中的四个: public,private,默认(不写就是默认),protected四种,这个在后面的学习中讲解,方法我们一般使用:public
返回值类型:就是方法在执行完成之后,给调用该方法返回什么结果,可以是我们前面学习的基本数据类型:int double Boolean….也可以死引用类型:String,其他类类型**,如果该方法不需要返回结果,就是使用:void关键字来表示,** 如果方法具有返回值,方法体重必须使用关键字return返回该值,返回值类型与该方法的返回值的类型一致.
方法名,就是方法的名称我们取得,注意java中的方法名第一个字母小写,也尽量使用字母,见名知意.
参数列表:就是方法需要什么数据,由调用者传递,参数列表的语法:数据类型1 参数名1,数据类型2 参数名2,数据类型3 参数名3**…****.**也就是说方法的参数可以有很多个,参数与参数之间有英文的逗号分隔,也可以没有参数.所以我们根据方法的参数可以把方法分为有参方法和无参方法.
2.4形参与实参
实参(argument):
全称为"实际参数"是在调用时传递给函数的参数. 实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参。 因此应预先用赋值,输入等办法使实参获得确定值。
形参(parameter):
全称为"形式参数" 由于它不是实际存在变量,所以又称虚拟变量。是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数.在调用函数时,实参将赋值给形参。因而,必须注意实参的个数,类型应与形参一一对应,并且实参必须要有确定的值。
形参和实参的区别
形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用。
实参出现在主调函数中,进入被调函数后,实参变量也不能使用。
形参和实参的功能是作数据传送。发生函数调用时, 主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。
1.形参变量只有在被调用时才分配内存单元,在调用结束时, 即刻释放所分配的内存单元。因此,形参只有在函数内部有效。 函数调用结束返回
主调函数后则不能再使用该形参变量。
2.实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形
参。 因此应预先用赋值,输入等办法使实参获得确定值。
3.实参和形参在数量上,类型上,顺序上应严格一致, 否则会发生“类型不匹配”的错误。
4.函数调用中发生的数据传送是单向的。 即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值
发生改变,而实参中的值不会变化。
5.当形参和实参不是指针类型时,在该函数运行时,形参和实参是不同的变量,他们在内存中位于不同的位置,形参将实参的内容复制一份,在该
函数运行结束的时候形参被释放,而实参内容不会改变。
而**如果函数的参数是指针类型变量****,**在调用该函数的过程中,传给函数的是实参的地址,在函数体内部使用的也是实参的地址,即使用的就是实参
本身。所以在函数体内部可以改变实参的值。
2.5对象
面向对象的内存结构图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XJ1MsEgh-1658653223899)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\1658651056797.png)]
2.6构造方法
概念:构造方法是一个特殊的方法,这个特殊方法用于创建实例时执行初始化操作;
它具有与类相同的名称;
它不含返回值;
它不能在方法中用return 语句返回一个值
2.7重载与重写
子类如果对继承的父类的方法不满意(不适合),可以自己编写继承的方法,这种方式就称为方法的重写。当调用方法时会优先调用子类的方法。
重写要注意:
a、返回值类型 b、方法名 c、参数类型及个数
都要与父类继承的方法相同,才叫方法的重写。
重载和重写的区别:
方法重载:在同一个类中处理不同数据的多个相同方法名的多态手段。 方法重写:相对继承而言,子类中对父类已经存在的方法进行区别化的修改。
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载要注意:
a、返回类型可以相同也可以不同 b、方法名字相同 c、参数不同
2.8封装
封装性
1.为什么要引入封装性?
①我们程序设计追求“高内聚,低耦合”。
②高内聚 :类的内部数据操作细节自己完成,不允许外部干涉;
③低耦合 :仅对外暴露少量的方法用于使用。
④隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。
2.封装性的几种体现
①将类的属性xxx私化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值
②不对外暴露的私有的方法
③单例模式(将构造器私有化),分为懒汉式和饿汉式
④如果不希望类在包外被调用,可以将类设置为缺省的。
3.权限修饰符
3.1 权限从小到大顺序为:private < 缺省 < protected < public
3.2 特殊说明:4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类,修饰类的话,只能使用:缺省、public
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1rS7Puq8-1658653223904)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\1658652242339.png)]
2.9
2.9继承
1.为什么有继承性
① 减少了代码的冗余,提高了代码的复用性
② 便于功能的扩展
③ 为之后多态性的使用,提供了前提
2.子类继承后的变化
①一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私的结构。只因为封装性的影响,使得子类不能直接调用父类的结构而已。
②子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。
3.继承的说明
①一个类可以被多个子类继承。
②Java中类的单继承性:一个类只能有一个父类
③子父类是相对的概念。
④子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
⑤子类继承父类以后,就获取了直接父类以及所间接父类中声明的属性和方法
3.0关键字:
1、static
一.static关键字的用途
“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”
这段话虽然只是说明了static方法的特殊之处,但是可以看出static关键字的基本作用,简而言之,一句话来描述就是:
方便在没有创建对象的情况下来进行调用(方法/变量)。
很显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。
static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。
1)static方法
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
因此,如果说想在不创建对象的情况下调用某个方法,就可以将这个方法设置为static。我们最常见的static方法就是main方法,至于为什么main方法必须是static的,现在就很清楚了。因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。
2)static变量
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
static成员变量的初始化顺序按照定义的顺序进行初始化。
3)static代码块
static关键字还有一个比较关键的作用就是用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
2、final
使用final关键字做标识有“最终的”含义。
1. final 修饰类,则该类不允许被继承。
2. final 修饰方法,则该方法不允许被覆盖(重写)。
3. final 修饰属性,则该类的该属性不会进行隐式的初始化,所以 该final 属性的初始化属性必须有值,或在构造方法中赋值(但只能选其一,且必须选其一,因为没有默认值!),且初始化之后就不能改了,只能赋值一次。
4. final 修饰变量,则该变量的值只能赋一次值,在声明变量的时候才能赋值,即变为常量。
3、this
1.this关键字代表当前对象
this.属性 操作当前对象的属性
this.方法 调用当前对象的方法。
2.封装对象的属性的时候,经常会使用this关键字。
3.当getter和setter函数参数名和成员函数名重合的时候,可以使用this区别。如:
4、super
在对象的内部使用,可以代表父类对象。
1、访问父类的属性:super.age
2、访问父类的方法:super.eat()
super的应用:
首先我们知道子类的构造的过程当中必须调用父类的构造方法。其实这个过程已经隐式地使用了我们的super关键字。 这是因为如果子类的构造方法中没有显示调用父类的构造方法,则系统默认调用父类无参的构造方法。 那么如果自己用super关键字在子类里调用父类的构造方法,则必须在子类的构造方法中的第一行。 要注意的是:如果子类构造方法中既没有显示调用父类的构造方法,而父类没有无参的构造方法,则编译出错。
(补充说明,虽然没有显示声明父类的无参的构造方法,系统会自动默认生成一个无参构造方法,但是,如果你声明了一个有参的构造方法,而没有声明无参的构造方法,这时系统不会动默认生成一个无参构造方法,此时称为父类有没有无参的构造方法。)
四、初始化
1、初始化父类再初始化子类
2、先执行初始化对象中属性,再执行构造方法中的初始化。
基于上面两点,我们就知道实例化一个子类,java程序的执行顺序是:
父类对象属性初始化---->父类对象构造方法---->子类对象属性初始化—>子类对象构造方法
————————————————
用父类的构造方法,而父类没有无参的构造方法,则编译出错。
(补充说明,虽然没有显示声明父类的无参的构造方法,系统会自动默认生成一个无参构造方法,但是,如果你声明了一个有参的构造方法,而没有声明无参的构造方法,这时系统不会动默认生成一个无参构造方法,此时称为父类有没有无参的构造方法。)
四、初始化
1、初始化父类再初始化子类
2、先执行初始化对象中属性,再执行构造方法中的初始化。
基于上面两点,我们就知道实例化一个子类,java程序的执行顺序是:
父类对象属性初始化---->父类对象构造方法---->子类对象属性初始化—>子类对象构造方法
————————————————