Java学习 -- 面向对象概述与封装性
Posted 庸人冲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习 -- 面向对象概述与封装性相关的知识,希望对你有一定的参考价值。
面向对象思想
概述
Java语言是一种面向对象的程序设计语言,而面向对象思想是一种程序设计思想,我们在面向对象思想的指引下,使用Java语言去设计、开发计算机程序。 这里的对象泛指现实中一切事物,每种事物都具备自己的属性和行为。面向对象思想就是在计算机程序设计过程中,参照现实中事物,将事物的属性特征、行为特征抽象出来,描述成计算机事件的设计思想。 它区别于面向过程思想,强调的是通过调用对象的行为来实现功能,而不是自己一步一步的去操作实现。
面向过程与面向对象的区别
面向过程:当需要实现一个功能时,每一个具体的步骤都要亲历亲为,详细处理每一个细节。
面向对象:当需要实现一个功能时,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我们做事。
举例
洗衣服:
面向过程:把衣服脱下来–>找一个盆–>放点洗衣粉–>加点水–>浸泡10分钟–>揉一揉–>清洗衣服–>拧干–>晾起来
面向对象:把衣服脱下来–>打开全自动洗衣机–>扔衣服–>按钮–>晾起来
区别
面向过程:强调步骤。
面向对象:强调对象,这里的对象就是洗衣机。
代码展示
public class Demo01PrintArray {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
// 要求打印格式为:[1, 2, 3, 4, 5]
// 面向过程实现
System.out.print("[");
for(int i = 0; i < arr.length; i++){
if(i < arr.length - 1) {
System.out.print(arr[i] + ", ");
} else {
System.out.println(arr[i] + "]");
} // 需要关注功能实现的每一个细节
}
System.out.println("===============");
// 面向对象实现
System.out.println(Arrays.(arr));
// 不需要关注功能实现的每一个细节,只需要调用具有这个功能的方法即可。
//Arrays.toString()
//JDK提供的Arrays类中的toString() 方法
//Arrays.toString() 可以将数组转换成字符串格式
}
}
特点
面向对象思想是一种更符合我们思考习惯的思想,它可以将复杂的事情简单化,并将我们从执行者变成了指挥者。面向对象的语言中,包含了三大基本特征,即封装、继承和多态。
面向对象三条主线
- 类及类的成员:属性(成员变量)、成员方法、构造器、代码块、内部类。
- 面向对象三大特性:封装、继承、多态。
- 其它关键字:this, super, abstract, interface, final, package, import…
类和对象
什么是类
类:是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。
现实中,描述一类事物:
属性:就是该事物的状态信息。
行为:就是该事物能够做什么。
举例:小猫。
属性:名字、体重、年龄、颜色。
行为:走、跑、叫。
什么是对象
对象:是一类事物的具体体现。对象是类的一个实例,必然具备该类事物的属性和行为。
现实中,一类事物的一个实例:一只小猫。
举例:一只小猫。
属性:tom、5kg、2 years、yellow。
行为:溜墙根走、蹦跶的跑、喵喵叫。
类与对象的关系
类是对一类事物的描述,是抽象的。
对象是一类事物的实例,是具体的。
类是对象的模板,对象是类的实体。
类的定义
事物与类的对比
-
现实世界的一类事物:
属性:事物的状态信息。
行为:事物能够做什么。
-
Java中用class描述事物也是如此:
成员变量:对应事物的属性
成员方法:对应事物的行为
类的定义格式
public class ClassName {
//成员变量
//成员方法
}
定义类:就是定义类的成员,包括成员变量和成员方法。
成员变量:和以前定义变量几乎是一样的。只不过位置发生了改变。在类中,方法外,也叫类的属性,field。
成员方法:和以前定义方法几乎是一样的。只不过把static去掉,static的作用在面向对象后面课程中再详细讲解。
/*
定义一个类,用来模拟"学生",其中就有两个组成部分:
1、属性(是什么):
姓名、年龄、性别、...
2、行为(能做什么):
吃饭、睡觉、学习、...
对应到java的类当中:
1、成员变量(属性):
String name; // 姓名
int age; // 年龄
byte sex; // 性别 0:女,1:男,2:保密
2、成员方法(行为):
public void eat() {} // 吃饭
public void sleep() {} // 睡觉
public void study() {} // 学习
*/
public class Student {
// 成员变量
String name; // 姓名
int age; // 年龄
byte sex; // 性别
// 成员方法
public void eat(){
System.out.println("吃!");
}
public void sleep() {
System.out.println("睡!");
}
public void study() {
System.out.println("学!");
}
}
对象的使用
使用步骤
通常情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用,具体分为以下三个步骤:
-
导包:指出需要使用的类在什么位置。
如果类同属于一个包中(同一路径下),可以省略导包语句。
// 导包语句
// import packageName.className;
import cn.study.day07.demo03.Demo02Student;
- 创建
// className objName = new className();
Student stu = new Student();
- 使用
使用成员变量
// objName.memberVarName
stu.name = "张三";
使用成员方法
// objName.memberMethName(para,...) para可以是0或多个
stu.eat();
总结:想用谁,就用对象名点儿谁。
代码举例
例一
public class Demo02Student {
public static void main(String[] arg){
// 1. 导包
// 需要使用的Student类,和当前所在类同属一个包下,可以省略导包语句。
// 2. 创建
// className objName = new className();
Student stu = new Student();
// 根据Student类创建了一个stu的对象。
//3. 使用其中的成员变量
System.out.println(stu.name); // null
System.out.println(stu.age); // 0
System.out.println(stu.sex); // '\\u0000'
// Student类中没有给成员变量赋值
// 默认值与数组的规则相同
System.out.println("=====================");
// 改变对象当中的成员变量内容
stu.name = "张三";
stu.age = 18;
stu.sex = '男';
System.out.println(stu.name); // 张三
System.out.println(stu.age); // 18
System.out.println(stu.sex); // 男
System.out.println("=====================");
// 使用成员方法
stu.eat();
stu.sleep();
stu.study();
}
}
例二
/*
定义一个类,用来模拟"手机"事物
属性:品牌、价格、颜色...
行为:通话、短信...
对应到类当中:
成员变量(属性)
String brand;
double price;
String color;
成员方法(行为)
public void call(String who) {} // 打电话
public void sendMessage() {} // 群发短信
*/
public class Phone {
//成员变量
String brand; // 品牌
double price; // 价格
String color; // 颜色
//成员方法
public void call(String who){
System.out.println("给" + who + "打电话");
}
public void sendMessage() {
System.out.println("群发短信");
}
}
public class Demo03PhoneOne {
public static void main(String[] args) {
// 根据Phone类,创建一个名为one的对象;
Phone one = new Phone();
System.out.println(one.brand); // null
System.out.println(one.price); // 0.0
System.out.println(one.color); // null
System.out.println("===================");
// 给对象当中的成员重新赋值
one.brand = "小米";
one.price = 998.0;
one.color = "黑色";
System.out.println(one.brand); // 小米
System.out.println(one.price); // 998.0
System.out.println(one.color); // 黑色
System.out.println("===================");
one.call("雷军");
one.sendMessage();
}
}
成员变量默认值
成员变量如果未赋值,将会有一个默认值,规则如下:
- 整数类型,默认为0;
- 浮点类型,默认为0.0;
- 字符类型,默认为
'\\u0000'
; - 布尔类型,默认为
false
; - 引用类型,默认为
null
。
对象内存图
jvm
内存划分图
一个对象的内存图
堆中的成员变量是参考方法区.class中成员变量的信息创建的,其中的值就保存在堆(Heap)中。
堆中的成员方法保存的是一个地址值,指向了方法区中的成员方法信息。
进栈也叫压栈,先进栈的在后进栈的下面,后来的压着先来的。
出栈也叫弹栈,当方法执行完毕后会立刻从栈中销毁,main方法执行完毕,则程序结束。
先进后出,后进先出。
两个对象引用指向不同对象空间的内存图
对象名,也叫对象引用
从上图可以看到,两个对象在创建时,分别在堆区开辟了不同的内存空间,各自保存着本对象的成员变量和成员方法,但是这两块堆区内存空间同时指向了方法区里同一块空间。也就是它们的所具有的属性和功能是完全相同的,不同的是成员变量的值和成员方法调用的参数。
这会出现一个问题,每创建一个对象就需要在堆中开辟一块内存空间,但是里面保存的信息基本相同,因此十分浪费内存空间。
两个对象引用指向同一对象空间的内存图
对象在方法中的使用
使用对象类型作为方法的参数
任何数据类型都能作为方法的参数。
对象引用作为参数传递给方法的是对象的地址值。
public class Demo04PassObjParam {
public static void main(String[] args) {
Phone one = new Phone();
one.brand = "小米";
one.price = 998.0;
one.color = "土豪金";
mothod(one); // 传递的对象的地址
System.out.println(one);
}
public static void mothod(Phone param){
System.out.println(param);
System.out.println(param.brand); // 苹果
System.out.println(param.price); // 998.0
System.out.println(param.color); // 土豪金
}
}
使用对象类型作为方法的返回值
使用对象类型作为方法的返回值时,返回的是对象的地址值。
public class Demo05PhoneReturn {
public static void main(String[] args) {
// 用对象类型接收返回值
Phone two = getPhone();
System.out.println(two.brand); // 小米
System.out.println(two.price); // 799.0
System.out.println(two.color); // RoseGold
}
public static Phone getPhone() {
Phone one = new Phone();
one.brand = "小米";
one.price = 799.0;
one.color = "RoseGold";
return one;
}
}
成员变量和局部变量的区别
-
定义的位置不一样
局部变量:在方法的内部
成员变量:在方法的外部,直接写在类当中。
-
作用域不一样
局部变量:所在方法中可以使用,出了所在方法就不能使用。
成员变量:整个类全都可以通用。
-
默认值不一样
局部变量:没有默认值,要使用,必须先赋值。
成员变量:如果没有赋值,会有默认值,规则和数组一样。
-
内存的位置不一样
局部变量:位于栈内存。
成员变量:位于堆内存。
-
声明周期不一样
局部变量:随着方法进栈而创建,随着方法出栈而销毁。
成员变量:随着对象创建而创建,随着对象被垃圾回收而消失。
-
权限修饰符的使用不同,
public、 protected、 缺省、 private
局部变量:不能使用权限修饰符。
成员变量:可以使用权限修饰符。
public class Demo01VariableDifference {
String name; // 成员变量
public void methodA(){
int num = 20; // 局部变量
System.out.println(num);
}
public void methodB(int param) { //参数就是局部变量
// System.out.println(num); // 错误,num是methodA方法中的局部变量,不能在methodB中使用
System.out.println(name); // 成员变量,类中都可以使用
int age; // 局部变量
// System.out.println(age); // 局部变量未赋值不能使用
// 参数在方法调用时,必然会被赋值
System.out.println(param); // 这种写法没有问题
}
}
练习
创建一个学生类,三个属性,学号,年级和成绩。
创建20个学生类,其中学号从1开始到20结束,年级和成绩随机赋值。
Student类
// Student类
package cn.study.day26.demo05;
public class Student {
private int number = id; // 学号
private int state; // 年级
private int score; // 成绩
private static int id = 1; // 自增id
// 无参构造器
public Student() {
++id;
}
// 有参构造器,number和id变量自增,不允许设置
public Student(int state, int score) {
this.state = state;
this.score = score;
}
public String stuInfo() {
String info = "学号:" + this.getNumber() + ", 年级:" +this.getState() + ", 成绩:" + this.getScore();
return info;
}
// Getter/Setter
public int getNumber() {
return this.number;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
工具类
// 工具类
package cn.study.day26.demo05;
public class Utility {
// 遍历打印学生信息
/**
* @Description 遍历Student数组,并打印数组中学生对象的信息
* @author Joker
* @param stus 要遍历的数组
*/
public static void traverseStu(Student[] stus) {
for (int i = 0; i < stus.length; i++) {
System.out.println(stus[i].stuInfo());
}
}
/**
* @Description 筛选出Student数组中指定年级学的信息,并打印。
* @author Joker
* @param state 需要筛选出来的年级
*/
public static void searchStu(Student[] stus, int state) {
for (int i = 0; i < stus.length; i++) {
if (stus[i].getState() == state) {
System.out.println(stus[i].stuInfo());
}
}
}
/**
* @Description 使用冒泡排序算法,按照成绩属性给Student数组排序,从小到大。
* @author Joker
* @param stus 要排序的数组
*/
public static void bubbleSortStus(Student[] stus) {
for (int i = 0; i < stus.length - 1; i++) {
boolean flag = true;
for (int j = 0; j < stus.length - 1 - i; j以上是关于Java学习 -- 面向对象概述与封装性的主要内容,如果未能解决你的问题,请参考以下文章