Java之面向对象
- Java基础:
Java语言基础:
OOP(面向对象):Object oriented programming
Java语言是面向对象的语言,而C语言是面向过程的语言。
举个栗子:
面向过程编程思想:更接近于计算机的执行过程,对于程序员来说编写并不是很方便。
面向对象编程思想:更接近于人的思维方式,对于程序员来说编写更加方便。
优化:
将数据和方法封装为一个整体,java中将其称为类
2、类和对象
什么是类:类是一类事物的模板。
类的成员:成员变量(属性/数据) 方法。
什么是对象(实例):是一个具体存在的个体/实例。
类和对象的关系:
对象是经由类这个模板创建出来的一个具体的个体。
2.1对象的创建和访问
- 对象的创建:1) new 类名()、2) Person per = new Person()
等号右边是真正的创建对象,左边部分定义一个变量,指向此对象,此变量的意义:用于访问对象内部的内容使用。
2. 引用类型变量
a) 简称为引用 - 访问对象的成员变量,方法
a) 引用是用于访问对象内部的(非static)成员变量,(非static)方法
在一个类中定义的非static的成员变量和方法是属于对象的。
3.方法的重载:overload
问题:
可不可以在一个类中定义多个方法,多个方法的方法名是相同的?
class T{
//现金支付
public void pay(double money){…}
//刷卡支付
Public void pay(String id,String pwd){…}
//手机支付
Public void pay(String phone){…}
}
所谓方法的重载:是指在一个类中,允许出现多个方法名相同,但是参数列表不同的方法,构造了方法的重载(overload)。
参数列表不同的体现: - 参数个数不同
- 参数列表个数相同,类型不同
- 参数列表个数相同,类型不同、顺序不同。
方法签名即:方法名+参数列表。
通过方法签名可以唯一确定要调用的目标方法。
注意点:方法的重载和方法的修饰符,返回值类型无关的。
类中的成员:
成员变量 方法(非static,static方法,构造方法)
构造方法的语法结构:修饰符 类名(参数列表){方法体}。
任何一个类中都存在构造方法(不论是否已经人为给出)。
构造方法的作用:初始化成员变量
构造方法的分类:1)无参构造方法:修饰符 类名(){。。。}
2)有参构造方法:修饰符 类名(String name){。。。}
假如定义了一个类,如果类中没有人为写出构造方法,此时java会为这个类默认提供一个无参构造方法。如果人为写出了构造方法,那么java不再为类提供构造方法。
注意点:
- 如果一个类中人为写出了有参构造方法,而没有人为写出无参构造方法,此时这个类中不存在无参构造方法了。
- 构造方法的作用:不论无参还是有参构造方法,作用都是初始化数据的。
- 一个类中无参构造方法最多只能有一个,有参构造方法可以有多个。
一个类中的无参构造方法和有参构造方法构成了构造方法的重载。
this关键字:
用于任何的非static方法体中,this是一个引用,指向调用当前方法的对象。
this通常情况下都可以省略不写,但是有一种情况不可以省略(有歧义的情况)。
是非static方法能直接调用非static方法的关键。
3. JAVA内存管理
3.1程序,无论代码还是数据,都需要存储在内存中。JVM为Java程序提供并管理所需要的内存空间。JVM保存的内容:代码 变量 数组 对象。
JVM内存分为“堆”、“栈”和“方法区”三个区域,分别用于存储不同的数据。
1) 栈:stack
a) 保存的数据:局部变量
b) 栈帧区域:执行一个方法,会在栈中为该方法开辟一块栈帧区域,用于保存此方法体中出现的所有局部变量。
2) 堆:heap
保存的数据:对象创建出来的每个对象内部的数据都是属于对象,所以(非static)成员变量也保存在堆中。数组也是对象
局部变量的生命周期:
局部变量会随着方法的执行结束而从内存中销毁
成员变量的生命周期:
随着对象的创建而产生,随着对象的销毁而销毁、成员变量的生命周期和对象的生命周期保持一致。
对象的生命周期:
执行到new代码时创建,如果有引用指向对象,表示对象正在被使用,当某一个对象不被任何引用指向时,此时这个对象就成为了垃圾。成为垃圾之后应该被销毁,而对象的销毁是由java已经提供的GC机制来完成。GC机制:garbage collection(垃圾回收器)GC是用于回收垃圾(没有任何引用指向的对象)的。
工作原理:
GC会不定时去内存中回收垃圾。GC对程序员来说是透明的。换言之:对象的销毁时间程序员是无法得知的。一个对象没有任何引用指向时,成为了垃圾,不一定是成为垃圾的瞬间被回收,有可能是一段时间之后才被销毁的。但是当jvm内存不足时,GC一定会进行回收。
垃圾回收机制:
- 垃圾回收器(Garbage Collection,GC)是JVM自带的一个功能,用于回收没有任何引用指向的对象。Java程序员不用担心内存管理,因为垃圾收集器会自动进行回收管理。
- GC判断对象是否可以回收的依据判断该对象是否有引用指向,因此当确定该对象不再使用时,应该及时将其引用设置为null(一般情况下不必手动设置)。
a) 问题:
i. 如果有多个对象,在使用完之后,没有将其引用的值置为null,这种现象的累积会造成什么后果?
b) 内存泄漏:分配出现的内存回收不回来。
c) 内存溢出:内存剩余资源不足以分配给请求的资源。
d) 二者的关系:
内存泄漏累积到一定程度会造成内存溢出。
我们在写程序时,一定要避免出现内存泄漏问题
出现内存溢出,不一定是由于内存泄漏引起的。
b) 一 般 情 况 下 , 当 我 们 需 要 GC 即 刻 回 收 无 用 对 象 时 , 可 以 调 用 System.gc() 方法。System.gc() 用于建议虚拟机马上调度GC回收资源。
3) 方法区:类的所有信息
方法区用于存放类的信息,Java程序运行时,首先会通过类装载器载入类文件的字节码信息,经过解析后将其装入方法区。类的各种信息都在方法区存储。
Java程序的执行机制:
先编译后运行(解释执行)。编译:.java.class(字节码文件)、运行(解释执行):运行的是.class文件中的内容。
运行步骤:
1).解释(加载类信息):将所有的.class文件解析出来加载到方法区(程序运行一次只加载一次)2).执行。
Java是一门面向对象的语言,OOP 面向对象有三大特征:封装 继承 和多态。
继承的目的:为了提高代码的复用率,将公共的内容提取到父类中去,子类继承父类,子类中可以直接使用父类中的公共内容。
术语:
父类/基类/超类:superclass、子类/派生类:subclass
继承的代码实现:extends关键字:
用法: 子类 extends 父类。
继承的特点:
1) Java中类的继承具有单继承的特性:
a) 单继承是指一个子类只能有一个父类,不能有多个父类。
b) 但是一个父类可以有多个子类。
2) 继承具有传递性:
举个栗子:
a) class A extends B
b) class C extends A
那么C类可以继承B类中的公共的内容
java中不继承的成员:
1)构造方法、2)私有成员:private、3)static成员
访问控制修饰符:
作用:用来描述所修饰的内容的可访问范围的。
(a) public ( b) private:私有的
继承中的构造方法的调用关系:
创建子类对象,会先调用父类的构造方法,再继续执行子类的构造方法。
– super()
注意点:
- super()可以省略不写,但是不写依然存在。
- 如果要在构造方法中添加一些代码,这些代码一定是位于super()的下面的。
Java构造器默认生成的都是调用父类的无参构造方法,可以人为在构造方法中定义是去调用父类的无参构造方法还是有参构造方法。
继承中方法的重写:
重写:override
子类对父类中的某个方法的方法体进行重新实现。
重写规则:
- 签名(方法名、参数列表)一致
- 子类的访问控制修饰符范围不能<父类的
- 子类的返回类型允许是父类方法返回类型的子类型
a) 如果父类中的方法的返回值类型是基本数据类型,那么子类重写父类的这个方法的返回值类型只能和父类保持一致。
b) 如果父类中的方法的返回值类型是引用类型时,那么子类中重写这个方法,重写方法的返回值类型可以和父类保持一致,也可以是父类中返回类型的子类类型。
访问控制修饰符:
a) public 公共的 : 同一项目下所有的都可以访问。
b) protected 受保护的 : 本包下 以及不同包下的子类可以访问。
c) default 默认的 : 只有本包下可以访问。
d) private私有的 : 只有本类可以访问。
当子类对象的重写方法被调用时(无论是通过子类的引用调用还是通过父类的引用调用),运行的都是子类重写后的版本。
通过子类的引用指向子类对象
Student stu = new Student();
## 对象的向上造型:
通过父类的引用指向子类对象
Student extends Person{}
Person stu = new Student();
通过父类的引用指向子类对象
向上造型好处:可以根据不同的实现,实现不同的业务逻辑。
向上造型的缺点:不能访问到子类中特有的成员
解决办法:向下造型
向下造型注意点:向下造型造型成的类型必须和运行期的对象类型相同(相关)
举个栗子:
Person stu = new Student();
//正确的
Student stu1 = (Student)stu;
2.
Person per = new Person();
//错误的
Student stu = (Student)per;
3.
Person tea = new Teacher();
//错误的
Student stu = (Student)tea;
重写中super关键字的使用:
super和this一样,都是引用、方法的重写中super关键字通常用于实现子类中对父类中的某一方法进行功能扩展。
例如:
class Super{
test(){
// 完成特定功能
}
class Sub extends Super{
//要对test方法的功能进行扩展
test(){
super.test();
//扩展的功能
}
}
}
重载(overload)和重写(override)的区别
重载和重写描述的两种完全不同的现象。因为二者的名字类似,所以要进行区分。
重载:在同一个类中,存在多个方法名相同,参数列表不同的方法
重写:在具有继承关系的两个类中,子类对父类中的某个方法的方法体进行重新实现。
区别:重载在编译期绑定方法,重写在运行期绑定方法
4.封装:
封装类:将对象的数据和行为封装为一个整体,并尽可能地隐藏对象的内部实现细节、写封装类时应遵循数据私有化,行为公开化,目的:保证数据的安全性。
5.static和final关键字
static关键字:static可以修饰三类内容,不论修饰的是什么,一旦用static修饰,表示所修饰的内容是属于类的。因为是属于类的,所以通过类来调用,体现在代码上为:通过类名来调用。
举个栗子:
class T{
static int a;
static void demo(){}
}
class Test{
main:
System.out.println(T.a);
T.demo();
}
特点:static成员变量不会随着对象的创建而重新初始化,会随着程序的重新加载而重新初始化。
举个栗子:
public class StaticDemo {
static int a;
int b;
public static void main(String[] args) {
StaticDemo demo = new StaticDemo();
demo.a = 5;
demo.b = 10;
System.out.println(a); //5
System.out.println(demo.b); //10
StaticDemo demo2 = new StaticDemo();
System.out.println(demo2 .a); //5
System.out.println(demo2.b); //0
}
}