My-Blog-Hexo/source/_posts/Java面向对象基础.md
2024-12-18 20:27:43 +08:00

332 lines
10 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Java面向对象基础
date: 2020-09-30 12:17:29
tags:
- Java
- 面向对象
categories:
- Java基础
---
## 初识面向对象
### 面向过程和面向对象
**面向过程思想:**
* 是把模型分解成一步一步的过程。步骤清晰简单,第一步做什么,第二步做什么……
* 面向过程适合处理一些较为简单的问题
<!-- more -->
**面向对象思想:**
* 物以类聚,<span style="color:red">分类</span>的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
* 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
<span style="color:red">对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路、来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。</span>
### 什么是面向对象
面向对象编程(Object-Oriented Progrsmming,OOP)是一种通过对象的方式,把现实世界映射到计算机模型的一种编程方法。
**面向对象编程的本质就是:**<span style="color:red">以类的方式组织代码,以对象的形式封装数据。</span>
**面向对象的核心思想:**
* **三大思想:**面向对象思想从概念上讲分为以下三种OOA、OOD、OOP
* OOA面向对象分析Object Oriented Analysis
* OOD面向对象设计Object Oriented Design
* OOP面向对象程序Object Oriented Programming
* **抽象**
* **三大特性**
* 封装性:所有的内容对外部不可见
* 继承性:将其他的功能继承下来继续发展
* 多态性:方法的重载本身就是一个多态性的体现
从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
从代码运行角度考虑是先有类后有对象。类是对象的模板。
## 方法
具体可参考 [java方法](http://pengspace.top/2020/05/30/Java方法/#more),此处只做一些补充说明
#### 方法的定义
##### 修饰符
##### 返回类型
##### break和return的区别
`break`:结束整个循环
`continue`:结束本次循环
`return`: 结束方法,返回一个结果
##### 方法名
注意规范,首字母小写和驼峰原则。见名知意
##### 参数列表
(参数类型,参数名)…
##### 异常抛出
```java
修饰符 返回值类型 方法名(参数类型 参数名) throws 异常类型( IOException) {
...
方法体
...
return 返回值;
}
```
#### 方法的调用
##### 静态方法和非静态方法
<span style="color:red">非静态方法不能通过类名直接调用,若要调用非静态方法,必须先实例化该方法所在类的对象,通过对象来调用。</span>
<span style="color:red">静态方法可以通过类名直接调用,也可以通过对象调用。</span>
```java
//Demo.java
public class Demo {
public static void main(String[] args) {
Student.say1();
//Student.say2(); 错误,非静态方法不能通过类名直接调用
Student stu = new Student(); //实例化对象
stu.say1();
stu.say2();
}
}
//Student.java
public class Student {
//静态方法
public static void say1(){
System.out.println("静态方法");
}
//非静态方法
public void say2(){
System.out.println("非静态方法");
}
}
```
<span style="color:red">静态方法是和类一起加载的,而非静态方法是在类实例化后才会起作用的</span>,所以在类中,也不能在静态方法中去调用非静态方法
##### 形参与实参
> 形式参数:是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。
>
> 实际参数:在调用有参函数时,主调函数和被调函数有数据传递关系。在主调函数中调用一个函数时,函数后面括号中的参数称为“实际参数”。
```java
public class Demo {
public static void main(String[] args) {
Demo demo = new Demo();
//实际参数和形式参数的类型要对应
int add = demo.add(1,2); //1和2是实参
}
public int add(int a,int b){ //a和b是形参
return a+b;
}
}
```
实际参数是调用有参方法时真正传递的内容,而形式参数是用于接收实参内容的参数。
##### 值传递与引用传递
<span style="color:red">Java中都是值传递。</span>
后续会专门写一篇来讲述Java为什么都是值传递。
## 类与对象
### 类与对象的关系
<span style="color:red">类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。</span>比如Person类、Pet类、Car类等这些类都是<span style="color:red">用来描述/定义某一类具体事物应该具备的特点和行为。</span>
<span style="color:red">对象是抽象概念的具体实例。</span>比如 你就是个人的具体实例,你家的旺财就是狗的一个具体实例。<span style="color:red">能够体现出特点、展现出功能的是具体的实例,而不是一个抽象的概念。</span>
### 类的定义格式
```java
class 类名称{
成员属性
成员方法
}
属性定义格式
数据类型 属性名;
属性定义并赋值的格式
数据类型 属性名 = 初始化值;
方法定义格式
权限修饰符 返回值类型 方法名(形式参数列表){
//方法体
return 返回值
}
```
### 对象的创建
使用`new`关键字创建对象。
使用`new`关键字创建对象的时候,除了为对象分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
```java
一个类要想真正的进行操作则必须依靠对象对象的定义格式如下:
类名称 对象名称 = new 类名称();
如果要想访问类中的属性或方法方法的定义则可以依靠以下的语法形式
访问类中的属性 对象.属性 ;
调用类中的方法 对象.方法(实际参数列表) ;
```
### 构造方法(构造器)详解
一个类中即使什么都不写,也可以实例化该类的对象,那是因为,类中默认存在一个方法,就是<span style="color:red">**构造器**</span>
类中的<span style="color:red">**构造器**</span>也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
* 必须和类的名字相同
* 必须没有返回类型也不能写void
我们在使用`new`关键字实例化对象时,本质是在调用构造器,来初始化值。
构造器可以重载,但注意,<span style="color:red">一旦你定义了有参构造器,如果还想使用无参构造,无参构造器就必须也显式定义。</span>
```java
//Person.java
public class Person {
//一个类即使什么都不写,它也会存在一个方法
//默认构造器 public Person(){}
String name;
//无参构造器
public Person(){
}
//有参构造器:一旦定义了有参构造,无参构造器就必须显式定义
public Person(String name){
this.name = name;
}
}
//Application.java
public class Application {
public static void main(String[] args) {
//new 实例化对象
Person person = new Person();
Person person1 = new Person("brian");
System.out.println(person.name); //null
System.out.println(person1.name); //brian
}
}
```
### 匿名对象
```tex
没有对象名称的对象 就是匿名对象。
匿名对象只能使用一次因为没有任何的对象引用所以将称为垃圾等待被GC回收。
只使用一次的对象可以通过匿名对象的方式完成,这一点在以后的开发中将经常使用到。
```
```java
public class Application {
public static void main(String[] args) {
int num = new Math().sum(100,20); //匿名对象
}
}
class Math {
int sum(int x,int y){
return x+y;
}
}
```
## 创建对象内存分析
### 栈
> Java栈的区域很小 , 大概2m左右 , 特点是存取的速度特别快
>
> 栈存储的特点是, 先进后出
>
> 存储速度快的原因:
>
> 栈内存, 通过 '栈指针' 来创建空间与释放空间 !
>
> 指针向下移动, 会创建新的内存, 向上移动, 会释放这些内存 !
>
> 这种方式速度特别快 , 仅次于PC寄存器 !
>
> 但是这种移动的方式, 必须要明确移动的大小与范围 , 明确大小与范围是为了方便指针的移动 , 这是一个对于数据存储的限制, 存储的数据大小是固定的 , 影响了程序 的灵活性 ~
>
> 所以我们把更大部分的数据 存储到了堆内存中
>
>
>
> 存储的是:
>
> 基本数据类型的数据 以及 引用数据类型的引用!
>
> 例如:
>
> int a =10;
>
> Person p = new Person();
>
> 10存储在栈内存中 , 第二句代码创建的对象的引用(p)存在栈内存中
### 堆
> 存放的是类的对象 .
>
> Java是一个纯面向对象语言, 限制了对象的创建方式:
>
> <span style="color:red">所有类的对象都是通过new关键字创建 </span>
>
> new关键字, 是指告诉JVM , 需要明确的去创建一个新的对象 , 去开辟一块新的堆内存空间:
>
> 堆内存与栈内存不同, 优点在于我们创建对象时 , 不必关注堆内存中需要开辟多少存储空间 , 也不需要关注内存占用 时长 !
>
> 堆内存中内存的释放是由GC(垃圾回收器)完成的
>
> 垃圾回收器 回收堆内存的规则:
>
> 当栈内存中不存在此对象的引用时,则视其为垃圾 , 等待垃圾回收器回收 !
### 方法区
> 存放的是
>
> - 类信息
> - 静态的变量
> - 常量
> - 成员方法
>
> 方法区中包含了一个特殊的区域 ( 常量池 )(存储的是使用static修饰的成员)
### PC寄存器
> PC寄存器保存的是 当前正在执行的 JVM指令的 地址 !
>
> 在Java程序中, 每个线程启动时, 都会创建一个PC寄存器 !
### 本地方法栈
> 保存本地(native)方法的地址 !