面向对象
编程思想——面向对象(OOP)与面向过程(POP)的区别
1.面向过程:面向过程是一种以过程为中心的编程思想解决问题的方法与步骤。
2.面向对象:找"对象"解决问题。Object Oriented 相关的数据和方法组织为一个整体,这个整体就是类。
3.面向对象基于面向过程的,面向对象以面向过程为基础。解决简单问题时,建议用面向过程,解决复杂问题时,建议用面向对象。
类与对象
类:具有共同特性的一类事物的总称
对象:具体的事物
对象创建的内存图
栈: 正在执行的方法 ,局部变量
堆: new操作的对象 数组
方法区:类的信息、静态成员、常量池
对象创建的过程
1.类被加载到方法区,根据该类的main进行程序的执行。
2.此时,main方法进栈执行。由于代码第一句是一个类的对象的创建,类如果在方法区中 没有找到,就加载到方法区,如果找到,就直接使用。(类的加载只有一次。找到直接用,找不到才加载。)
3.根据类在main方法中为对象的引用变量开辟空间。
4.在堆中,根据类作为对象创建的模板,为类的对象开辟空间,并且为该类的对象的属性进行默认初始化。最终将内存首地址赋给引用变量,该引用变量就指向了类的对象。
5.为当前对象赋值.
结论
1.对象创建在堆中。
2.对于对象来说,对象的属性属于对象自身所有,并且在堆中开辟空间,不同的对象不能改变别的对象的属性值。
匿名对象
1.匿名对象: 没有名字的对象
2.格式: new 类名(参数)
3.作用: 1》 简化书写。 2》减少内存的开销。
4.区别: 1》 由于匿名对象,没有引用变量指向该对象,对于同一个对象来说,只能使用一次。引用变量可以多次使用。 2》对于属性赋值也存在该问题。 3》匿名对象一般只用于一次性调用时。
成员变量与局部变量、静态变量的区别
局部变量:生命周期随着方法的结束而结束、无初始化值,需要赋初始化值、不能使用修饰符,除了final以外、通过实例化对象调用方法、内存分配在栈中。
成员变量:生命周期随着对象的回收而释放、有默认初始化值,可以赋显示初始化值、可以使用修饰符、通过实例化对象调用、内存分配在堆中
静态变量:生命周期随着类的消亡而消亡、有默认初始化值,可以赋显示初始化值、可以使用修饰符、通过类名直接调用、所有对象共享、内存分配在方法区中
构造方法
1. 构造方法:constructor 格式: [权限修饰符] 类名(参数){}
2. 构造方法一般方法相比,最主要的区别在于,构造方法没有返回值类型。
3. 如果显式的声明了一个构造方法,编译器不会再为我们添加无参空构造,除非没有声明。 4. 构造方法的作用: ① 创建对象时,调用的方法。跟在new关键字后面。 ② 初始化。
构造方法与一般方法的区别
① 写法: 构造方法:[权限修饰符] 类名(参数){} 一般方法:[权限修饰符][修饰符] 返回值类型 方法名称(参数){}
② 名称: 构造方法:必须是类名 一般方法 方法名称可以是任意的标识符。
③ 调用: 构造方法: new 后面使用 用来创建对象时调用,可以初始化属性 一般方法: 对象.方法名称(参数)
④ 同一个对象: 构造方法: 调用一次,在对象创建时。 一般方法: 多次调用。
⑤ 构造方法可以调用一般方法,一般方法中不能直接调用构造方法。
对象的初始化
1.默认初始化 :开辟空间,为对象的属性赋默认值。
2.显式初始化:给属性直接赋值
3.构造初始化:在构造方法中为属性赋值。
顺序: 默认初始化 ---> 显式初始化---> 构造初始化
Setter与构造方法
1》 对象.属性 = 数据值
2》 构造方法:在创建对象时,并且对于同一个对象来说,只有一次。
3》 setter:对象创建完毕之后。并且对于同一个对象来说,可以无数次调用
面向对象的特征
封装 继承 多态 抽象
封装
1.封装最大体现:私有的属性 公有的方法。
2.关键字: private:私有的,权限:本类中访问,出了本类就不能访问。
3.公有的方法:
1》 getter方法:获取 格式: public 属性数据类型 get属性的名称(){ return 属性; }
2》 setter方法:设置 格式: public void set属性的名称( 属性的数据类型 属性名称){ this.属性= 属性名 }
4.封装好处:
- 提高代码的复用性。
2》 提高代码的安全性。
继承
继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
1.提高了代码的复用性和维护性。
2.关键字: extends 格式: class 子类 extends 父类{ }
3.子类:表示subclass 父类:表示superclass
4.继承: 对于子类来说 ,继承父类所有的属性和方法。除了:由private修饰的成员,不能被继承 、构造方法不能被继承。
5.继承的特点:
① 单继承 :对于extends后面的父类,有且仅有一个。
② 多重继承:可以"祖孙辈"的反复继承
多态
指为不同数据类型的实体提供统一的接口 所谓多态意指相同的行为给予不同的对象会引发不同的动作。
里氏代换原则:任何基类(父类)可以出现的地方,子类一定可以出现
多态的分类:
① 向上转型: 父类引用指向子类对象。 ② 向下转型
多态的好处:
① 提高代码的扩展性。 ② 提高代码的复用性。
静态
实例共享。(共产主义) 实例:对象
- static修饰的成员在方法区的静态区中。
2>static修饰的成员实例共享。
3> static修饰的成员来说,所有的对象都能够改变该成员。
静态成员,随着类的加载而加载。类加载完毕之后,静态成员初始化也完毕了。并且只加载一次。 调用格式: 类名.方法名称(参数)/属性
静态成员又叫类成员。 非静态成员又叫实例成员。 凡是static修饰的成员,统称为静态成员,没有static修饰的成员,称为非静态成员。
静态变量与非静态变量的区别
内存分配:静态变量在类初始化时,就存在于内存当中,直到它所在的类的程序运行结束时才消亡;非静态变量需要被实例化后才会分配内存。
生存周期:静态变量生存周期为类的存在周期,类存在就存在;非静态变量的存在周期取决于实例化的类的存在周期。
调用方式:静态变量只能通过“类.静态变量名”调用,类的实例不能调用;非静态变量当该变量所在的类被实例化后,可通过实例化的类名直接访问。
共享方式:静态变量是全局变量,被所有类的实例对象共享;非静态变量是局部变量,不共享。
访问方式:静态成员不能访问非静态成员;非静态成员可以访问静态成员。
方法重写与重载
方法重写:
override 在具有继承关系的子父类的子类中,父类的方法由于不满足子类的需求,由子类重写父类的方 法。称为方法的重写。
重写的规则:
- 方法名称相同
- 参数列表相同
- 返回值目前相同
4》 子类的权限修饰要大于等于父类
方法的重载:
同一个类中,方法名称相同,参数列表不同,与返回值无关
Super与this关键字
Super的用法:
1.指代父类 格式: super.父类的属性/父类的方法() 使用场景: 当父类的属性或方法与子类的重名时,才会去使用super
2.指代父类构造方法 格式: super(参数)
注意:
① super无论是否显式的书写,super()都是在子类构造方法的第一行,通过super()的形式,来 继承父类的所有的成员,其中super()表示默认的调用,如果需要指定调用父类的有参构造,可以通过 super(参数)的形式,来调用。
② 对于一个类来说,如果显式的声明了构造方法,特别是有参构造,建议加一个无参构造。 ③ 对于super指代构造方法,必须放在构造方法的第一行。
This的用法:
① 指代当前类的当前对象。 格式: this.属性/方法(参数)
② 指代构造方法:
1》 必须放在构造方法中
2》 构造方法的第一行。 格式: this(参数)
this与super指代构造方法时,需要注意:
① 由于this与super都必须放在第一行,有this无super,有super无this。
② super只要是有父类,构造方法第一句就默认是super。
③ 调用this与super,避免递归。
this与super指代对象时:
this:当前类的当前对象 super:当前类的父类对象
注意:
① 对于super来说,从super位置向上找起。
② 对于this来说,从this位置开始向上找起。
③ 格式: this/super.属性/方法名称(参数)
④ super只能在子类中使用。不能在其它位置使用。
⑤ super/this不能在静态方法中使用
super与this用法:
① 指代构造方法 格式: this/super(参数)
② 指代对象 格式: this/super.属性/方法(参数)