Java 面向对象基础详解

一.面向对象思想

万物皆对象
计算机中的对象是对现实中的对象个体的一个完全的模拟
1 软件开发目的
利用计算机的高效运算来改造世界,为生活中的问题提供解决方案,提高工作效率

2 分析与设计软件的思维方式
分析问题--》设计程序
1)面向过程 (c语言)
2)面向对象 (c++,C#,java语言)

3 面向过程(OPP) vs 面向对象(OOP)
装配电脑过程 - 事事亲力亲为 (面向过程)
买组装机,或者叫朋友帮忙组装 --> 调用(面向对象)


ps: 面向过程一开始就考虑实现的流程和细节,面向对象一开始考虑的是有哪些类型和对象在相互协作
面向对象的思维是最接近人类自然的思维方式

二.面向对象抽象步骤

(1)找出类

1 何为类
类型的类,归类的类
就是人在认识分析世界中对具有相同特点的事物一个总称,它就是一个概念来的
就是存在于人脑中的一个概念,在分析过程中,经常叫它为概念模型
类:就是某类对象的抽象,是某类对象的集合。

2 分析得到类的过程

 

3 类的示例

class Person{
int eyes = 2;//2个眼睛
int hands = 2;//2只手
int legs = 2;//2条腿

//直立行走()
void walk(){
System.out.println("直立行走");
}
//吃()
void eat(){
System.out.println("吃");
}
//睡()
void sleep(){
System.out.println("睡");
}
//思考()
void think(){
System.out.println("思考");
}
}

 


(2)找出属性

1 何为属性
一类事物都有相同的一些静态特征(状态),例如人都有年龄,我们将这个静态特征(状态)写到类里,这个特征(状态)就叫做类的属性,或者叫成员变量,也叫实例(对象)变量,字段等等。
虽然人都有年龄这个属性,它的取值是可以不一样,每个个体(对象)的年龄可以赋一个不同值

2 实例变量的默认值
实例(成员)变量,编译器在编译的时后会给它赋默认值
不同的类型,编译器会赋上不同类型的默认值


引用类型 --> null
byte -->0
short -->0
int --> 0
long -->0
float -->0.0
double -->0.0
char -->'\u0000'
boolean --> false


3 全局变量 vs 局部变量
1)位置不同
实例变量是在类里面、方法外面
局部变量定义在方法内或者局部代码块内
2)是否需要显式初始化
局部变量没有初始化之前是不能使用的(编译器),先赋值后使用
实例变量可以直接使用,不赋值时会有赋以相应类型的默认值
3)生命周期及作用域
局部变量:只在方法体或者语句块中
实例变量:与对象的生命周期相同
4)在内存的位置
局部变量在方法栈中
实例变量在对象堆中

(3)找出方法

1 何为方法
方法就是某类事物共同的行为,功能,也就是动态特征。

2 方法的基本格式
[修饰符…] 返回类型 方法名([形参列表...]){语句块;}
用helloworld程序的main方法帮助记忆。
void : 表示不需要返回值
1)无参方法
有返回值的无参方法
无返回值的无参方法。
2)有参方法
有返回值的有参方法
无返回值的有参方法。
方法的参数列表可以有多个,可以是基本数据类和引用类型

3 形参和实参
声明的时候叫形参,就是一个占位符
发生调用的时候,传入的实际叫是实参

4 注意
形参是局部变量
形参作为局部变量,是不需要赋值就可以使用

(4)优化设计   

继承的使用。

三.对象

1 何为对象
计算机程序类,是创建计算机中对象的模板或者说蓝本
类 - 》设计图纸
对象就是实际存在的个体,也叫实体。可以是看得到,也可以是看不到(比如一个创意)
万物皆对象
计算机中的对象是对现实中的对象个体的一个完全的模拟

2 创建对象
使得new关键来创建


Person p = new Person();
p.walk();//.调用运算符s
p.sleep();
p.eat();


四.引用变量

1 何为引用变量
除去基本数据类型的变量,剩下的都引用变量
int a;//基本数据类型变量
String s;//引用变量
Person p;//引用变量
引用变量问题试图去牵引着另一个存在的对象个体。

2 注意事项
引用变量牵引一个对象,并不是装着一个对象
基本数据类型的变量装的是值本身,引用类型变量装的是对象的起始地址
一个对象就像一个气球,气球可以用多根绳子牵引着,同理一个对象也可以被多个变量引用
Person p2 = p;

 


ps:
1 一个对象可以被多个引用变量引用,如果没有任何变量引用该对象时,该对象会被垃圾回收器回收
2 在一个空引用上访问属性或调用方法,会抛出空指针异常(NullPointException)
Exception in thread "main" java.lang.NullPointerException

五.方法栈与对象堆

1 jvm的内存分布

 


2 各部分介绍
1)栈
方法栈,程序在运行会将所有调用的方法都压入栈。

保存局部变量的值,包括:

1.用来保存基本数据类型的值;

2.保存类的实例即堆区对象的引用(指针)。也可以用来保存加载方法时的帧,FILO(first in last out 先进后出)

2)堆
对象堆(垃圾堆),用来存放动态产生的数据,比如new出来的对象。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次
3) 常量池
JVM为每个已加载的类型维护一个常量池,常量池就是这个类型用到的常量的一个有序集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的符号引用(1)。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。常量池存在于堆中
4) 代码段
用来存放从硬盘上读取的二进制字节码
5)数据段
用来存放static定义的静态成员

 


六.传参方式

1 java的传参方式
1)值传递 - 基本数据类型传递数据值本身
2)引用传递 - 传递对象地址值

ps:严格意义上来说,都是值传递

2 引用传递注意事项
引用a的值传递给引用b,此时通过b去改变对象的内容,通过a访问到的内容是b改变后的内容

 

七.构造方法

1 何为构造方法
构造方法是一种特殊方法,也叫构造函数,或构造器
名字必须和类名相同,并且没有返回类型
2 构造方法作什么用
用来初始化成员变量
提供了一个机会给开发者,让开发者有一个时机介入到对象的构建过程中

3 构造方法的语法
1)如果一个类没有定义构造方法,编译器会提供一个默认的构造方法(无参)
2)构造方法可以有多个,构成重载
3)如果类已经提供了一个构造方法,编译器不会提供默认的构造方法
4)好的建议:如果我们定义了有参数的构造方法,一般情况下会同时提供一个无参的构造方法

4 构造方法在什么时候调用
Cat c = new Cat();
1)在栈中创建c变量
2)在堆中分分配对象内存
3)调用该对象的构造方法
4)默认初始该对象成员变量,对象创建成功。
5)把对象地址赋值给c变量

 

八.this引用

(1)解决命名冲突

当成员变量(实例变量)和局部变量重名时,局部变量优先,成员变量会被局部变量覆盖,此时用this来解决

//有参的构造方法


public Cat(String name,int age,String color){
this.name = name;
this.age = age;
this.color = color;
}


 

 

(2)调用重载的构造方法

九.垃圾回收

1 什么是垃圾回收器(Garbage collection)
jvm运行的时候会在后台运行一个低优先级线程,它会不间断的去扫描内存的使用情况,当发现堆中对象没任何一个引用变量牵引时,就把这个对象视为垃圾,该线程就会回收这个对象,然后释放这个对象占用的内存。

2 为什么需要垃圾回收器
C++的程序员使用内存都是自己分配的,使用完后也是由自己回收。这样子很容易造成疏忽,忘记释放。当内存不断的分配使用,就会消耗掉所有内存,这时就会出现内存溢出或者其它的问题。
java为了防止由于开发者疏忽造成的内存溢出的这种现象,提供了垃圾回收器来自动的回收不用对象释放占用的内存。
即使有垃圾回收器,jvm内存仍然可以耗尽。

3 垃圾回收器的回收时机
回收的时机是不确定,跟实现它的算法有关系,垃圾回收的算法有很多,不同的jdk可能采用的算法不一样。
开发者可以调用以下方法来建议垃圾回收器回收,但不能保证回收器会立即回收(像麦当劳的服务员)


System.gc();
Runtime.getRuntime().gc()



开发者可以主动将引用变量置null,垃圾回收器就可以扫描并回收它
Person p = new Person();
//调用p做事
p = null;

 

十.方法重载

1 何为方法重载(Overload)
定义:在同一个类中,方法名相同,参数列表不同, 与返回类型和修饰符无关的方法,叫方法重载,是一种静态多态性的表现。
2 重载的三个要素
1)在同一个类中
2)方法名相同,与返回类型和修饰符无关
3)参数列表不同(个数,顺序,类型)

3 重载调用
首先会找参数类型最接近的方法去执行

package com.tocean.ch06;
public class TestOverload2{
public static void main(String[] args){
A a = new A();
a.add(2,3);//编译出错
//a.add(2,3.0);
}
}
class A{
/*
public double add(int a ,int b){
System.out.println("----------add(int a ,int b)------------");
return a+b;
}*/
public double add(double a ,int b){
System.out.println("----------add(double a ,int b)------------");
return a+b;
}
public double add(int a ,double b){
System.out.println("----------(int a ,double b)------------");
return a+b;
}
}

 


十一.返回值 

1 返回值
返回值是一个方法执行后需要返回的结果,
如果一个方法需要返回给调用者执行结果,就必须先在声明该方法时要声明返回该结果类型
如果不需要返回,返回类型用void表示

2 注意
返回值可以是返回类型(大类型)兼容的小类型
参数也是一样,可以传递参数类型(大类型)兼容的小类型

原文地址:https://www.cnblogs.com/Transkai/p/10350302.html