首页 > 代码库 > Java基础面向对象
Java基础面向对象
Java基础第七天
面向对象思想
类与对象及其使用
对象的内存图
成员变量和局部变量的区别
匿名对象
封装(private)
this关键字
构造方法
static关键字
面向对象思想引入
前面我们讲过数组,当有多个数组都需要遍历时,我们可以将遍历的代码封装到方法中,需要遍历时,就调用相应的方法即可,提高代码的复用性。在对数组遍历的基础上继续增加需求,比如获取最值,数值逆序等,同样需要将这些功能封装到相应的方法中。这样继续封装会发现方法越来越多,于是就想能不能将这些方法继续进行封装呢?通过前面的讲解我们知道类是可以存放方法的,所以,我们就考虑使用类封装来这多个方法,将来再做数组的操作时,不用去找具体的方法,先找到这个类,然后使用这个类中的方法。这就是面向对象思想的编程方式。
面向过程思想概述
我们来回想一下,这几天我们完成一个需求的步骤:首先是搞清楚我们要做什么,然后在分析怎么做,最后我们再代码体现。一步一步去实现,而具体的每一步都需要我们去实现和操作。这些步骤相互调用和协作,完成我们的需求。
在上面的每一个具体步骤中我们都是参与者,并且需要面对具体的每一个步骤和过程,这就是面向过程最直接的体现。
那么什么是面向过程开发呢? 面向过程开发,其实就是面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然后由这些功能方法相互调用,完成需求。
面向过程的代表语言:C语言
面向对象思想概述
当需求单一,或者简单时,我们一步一步去操作没问题,并且效率也挺高。可随着需求的更改,功能的增多,发现需要面对每一个步骤很麻烦了,这时就开始思索,能不能把这些步骤和功能在进行封装,封装时根据不同的功能,进行不同的封装,功能类似的封装在一起。这样结构就清晰了很多。用的时候,找到对应的类就可以了。这就是面向对象的思想。接下来我们看看面向对象到底是什么?
1:面向对象思想
面向对象是基于面向过程的编程思想。
面向过程:强调的是每一个功能的步骤
面向对象:强调的是对象,然后由对象去调用功能
2:面向对象的思想特点
A:是一种更符合我们思想习惯的思想
B:可以将复杂的事情简单化
C:将我们从执行者变成了指挥者
举例:
买电脑:
面向过程:我的了解电脑--了解我自己的需求--找对应的参数信息--去中关村买电脑--讨价还价--买回电脑
面向对象:我知道我要买电脑 -- 班长去给我买 -- 班长就买回来了
洗衣服:
面向过程:把衣服脱下--找一个盆--放点洗衣粉--加点水--把衣服扔进去--搓一搓--清洗衣服--拧干--晾起来
面向对象:把衣服脱下--打开全自动洗衣机--扔进去--一键即可--晾起来
吃饭:
面向过程:去超市买菜--摘菜--洗菜--切菜--炒菜--盛起来--吃
面向对象:上饭店吃饭,你--服务员(点菜)--厨师(做菜)--服务员(端菜)--吃
家常事物,买洗衣机和去饭店太不划算了,所以,找个对象。
万事万物皆对象
面向过程思想和面向对象思想的代码举例
把大象装进冰箱
面向过程:
动作有哪些呢?
A:打开冰箱门
B:装进大象
C:关闭冰箱门
代码体现;
class Demo {
public static void main(String[] args) {
/*
System.out.println("打开冰箱门");
//打开冰箱门的东西,我现在仅仅是为了演示,就写了一个输出语句
//其实,它可能需要做很多操作。
//这个时候代码就比较多一些了
//假设我要多次打开冰箱门,
//代码一多,每次都写一遍,麻烦不
//我们就应该用方法改进
System.out.println("装进大象");
System.out.println("关闭冰箱门");
*/
//写了方法以后,调用就改变了
open();
in();
close();
}
public static void open() {
System.out.println("打开冰箱门");
}
public static void in() {
System.out.println("装进大象");
}
public static void close() {
System.out.println("关闭冰箱门");
}
}
面向对象:
我们怎么才能更符合面向对象思想呢?
A:有哪些类呢?
B:每个类有哪些东西呢?
C:类与类直接的关系是什么呢?
把大象装进冰箱的分析? (如何分析有哪些类呢?UML。名词提取法。)
A:有哪些类呢?
大象
冰箱
Demo
B:每个类有哪些东西呢?
大象:
进去
冰箱:
开门
关门
Demo:
main方法
C:类与类直接的关系是什么呢?
Demo中使用大象和冰箱类的功能。
代码体现:
class 大象 {
public static void in() {
System.out.println("装进大象");
}
}
class 冰箱 {
public static void open() {
System.out.println("打开冰箱门");
}
public static void close() {
System.out.println("关闭冰箱门");
}
}
class Demo {
public static void main(String[] args) {
冰箱调用开门
大象调用进去
冰箱调用关门
}
}
面向对象开发,设计,特征
面向对象开发
就是不断的创建对象,使用对象,指挥对象做事情
面向对象设计
其实就是在管理和维护对象之间的关系。
面向对象特征
封装(encapsulation)
继承(inheritance)
多态(polymorphism)
类与对象关系
我们学习编程语言,就是为了模拟现实世界的事物,实现信息化。比如:去超市买东西的计费系统,去银行办业务的系统。
我们如何表示一个现实世界事物呢:
属性 就是该事物的描述信息
行为 就是该事物能够做什么
举例:学生事物
现实世界中是如何描述一个事物的呢?
举例:学生
姓名,年龄,性别...
学习,吃饭,睡觉
属性:该事物的描述信息
行为:该事物能够做什么
我们学习编程语言,是为了模拟现实世界的事物的。
而我们学习的编程语言Java中最基本的单位是:类。
所以,我们就应该把事物通过类来体现出来:
由此,我们就得到了现实世界事物和类的对应关系:
事物:类:
属性成员变量
行为成员方法
类:是一组相关的属性和行为的集合。是一个抽象的概念。
对象:是该类事物的具体表现形式。具体存在的个体。
举例:
学生:类
班长:对象
类与对象的关系如图
类的定义
现实世界的事物
属性人的身高,体重等
行为人可以学习,吃饭等
Java中用class描述事物也是如此
成员变量就是事物的属性
成员方法就是事物的行为
定义类其实就是定义类的成员(成员变量和成员方法)
/*
事物:
属性事物的信息描述
行为事物的功能
类:
成员变量事物的属性
成员方法事物的行为
定义一个类,其实就是定义该类的成员变量和成员方法。
案例:我们来完成一个学生类的定义。
学生事物:
属性:姓名,年龄,地址...
行为:学习,吃饭,睡觉...
把事物要转换为对应的类:
学生类:
成员变量:姓名,年龄,地址...
成员方法:学习,吃饭,睡觉...
成员变量:和以前变量的定义是一样的格式,但是位置不同,在类中方法外。
成员方法:和以前的方法定义是一样的格式,但是今天把static先去掉。
首先我们应该定义一个类,然后完成类的成员。
*/
class Student { //定义变量(成员变量) String name; //性别 男1 女0 int sex; //年龄 int age; //地址 String address; //学习的方法 public void study() { System.out.println("学生爱学习"); } //睡觉的方法 public void sleep() { System.out.println("学习累了要睡觉"); } //吃饭的方法 public void eat() { System.out.println("学习饿了,要吃饭"); } }
/*
手机事物:
属性:品牌,价格,颜色...
行为:打电话,发短信,玩游戏...
手机类:
成员变量:品牌,价格,颜色
成员方法:打电话,发短信,玩游戏
*/
class Phone { //变量(成员变量) //品牌 String brand; //价格 int price; //颜色 String color; //打电话的方法 public void call(String name) { System.out.println("给"+name+"打电话"); } //发短信的方法 public void send(String name) { System.out.println("给"+name+"发短信"); } //玩游戏的方法 public void game() { System.out.println("玩游戏"); } }
学生类(讲解)
如何定义
按照事物到类的过程一步步分析
如何使用
创建对象:
类名 对象名 = new 类名();
对象名.成员变量
对象名.成员方法
/*
在一个java文件中写两个类:一个基本的类,一个测试类。
注意:文件名称和测试类名称一致。
如何使用呢?
创建对象使用。
如何创建对象呢?
格式:类名 对象名 = new 类名();
如何使用成员变量呢?
对象名.变量名
如何使用成员方法呢?
对象名.方法名(...)
*/
class Student { //定义变量(成员变量) String name; //性别 男1 女0 int sex; //年龄 int age; //地址 String address; //学习的方法 public void study() { System.out.println("学生爱学习"); } //睡觉的方法 public void sleep() { System.out.println("学习累了要睡觉"); } //吃饭的方法 public void eat() { System.out.println("学习饿了,要吃饭"); } } class StudentDemo { public static void main(String[] args) { //创建对象:类名 对象名 = new 类名(); Student banzhang = new Student(); //调用:对象名.成员变量 // 对象名.成员方法 System.out.println(banzhang.name); System.out.println(banzhang.age); System.out.println(banzhang.address); banzhang.study(); banzhang.sleep(); banzhang.eat(); Student s = new Student();//?创建对象 } }
/* 手机类的测试 */ class Phone { String brand; int price; String color; public void call(String name,int num) { System.out.println("给"+name+"打电话"+num); } public void send(String name) { System.out.println("给"+name+"发短信"); } public void game() { System.out.println("打游戏"); } } class PhoneDemo { public static void main(String[] args) { Phone iPhone = new Phone(); System.out.println(iPhone.brand); System.out.println(iPhone.price); System.out.println(iPhone.color); iPhone.game(); iPhone.call("家里",1283083); iPhone.send("家里"); } }
1个对象的内存图
一个对象的基本初始化过程
2个对象的内存图
3个对象的内存图
其中有两个引用指向同一个对象
成员变量和局部变量的区别
在类中的位置不同
成员变量 类中方法外
局部变量 方法内或者方法声明上
在内存中的位置不同
成员变量 堆内存
局部变量 栈内
生命周期不同
成员变量 随着对象的存在而存在,随着对象的消失而消失
局部变量 随着方法的调用而存在,随着方法的调用完毕而消失
初始化值不同
成员变量 有默认的初始化值
局部变量 没有默认的初始化值,必须先定义,赋值,才能使用。
/*
成员变量和局部变量的区别?
A:在类中的位置不同
成员变量:在类中方法外
局部变量:在方法定义中或者方法声明上
B:在内存中的位置不同
成员变量:在堆内存
局部变量:在栈内存
C:生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
D:初始化值不同
成员变量:有默认初始化值
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
注意事项:
局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
*/
class Varialbe { int a ;//成员变量 public void show(){ //错误: 可能尚未初始化变量i //int i ; int i = 0 ;//局部变量 System.out.println(i); } } class VariableDemo { public static void main(String[] args){ Varialbe v = new Varialbe(); v.show(); System.out.println(v.a); } }
形式参数问题
基本类型作为形式参数
引用类型作为形式参数
/*
形式参数的问题:
基本类型:形式参数的改变不影响实际参数
引用类型:形式参数的改变直接影响实际参数
*/
class ZhengShuJiSuan { public void sum(int a,int b) { int c = a + b; System.out.println(c); } } class ShuZuJiSuan { public void printArr(int[] arr) { int length = arr.length; System.out.println("length="+length); } } class LeiJiSuan { public void printMethod(Student student) { student.study(); student.eat(); } } class Student { public void study() { System.out.println("我要好好学习"); } public void eat() { System.out.println("我要好好吃饭"); } } class TestXingCan { public static void main(String[] args) { ZhengShuJiSuan zsjs = new ZhengShuJiSuan(); zsjs.sum(3,5); ShuZuJiSuan szjs = new ShuZuJiSuan(); int[] array = new int[5]; szjs.printArr(array); LeiJiSuan ljs = new LeiJiSuan(); Student student = new Student(); ljs.printMethod(student); System.out.println("Hello World!"); } }
匿名对象
匿名对象:就是没有名字的对象。【面试】
是对象的一种简化表示形式
匿名对象的两种使用情况
对象调用方法仅仅一次的时候
作为实际参数传递
/*
匿名对象:就是没有名字的对象。
匿名对象的应用场景:
A:调用方法,仅仅只调用一次的时候。
注意:调用多次的时候,不适合。
那么,这种匿名调用有什么好处吗?
有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
B:匿名对象可以作为实际参数传递
*/
class Student { public void show() { System.out.println("我爱学习"); } } class LeiMethod { public void print(Student s) { s.show(); } } class NoNameDemo { public static void main(String[] args) { Student student = new Student(); student.show();//第一个 new Student().show();//第二个 new LeiMethod().print(new Student());//第三个 //Student student = new Student(); new LeiMethod.print(new Student()); //System.out.println("Hello World!"); } }
封装概述
封装概述
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:
隐藏实现细节,提供公共的访问方式
提高了代码的复用性
提高安全性。
封装原则:
将不需要对外提供的内容都隐藏起来。
把属性隐藏,提供公共方法对其访问。
/*
定义一个学生类:
成员变量:name,age
成员方法:show()方法
我们在使用这个案例的过程中,发现了一个问题:
通过对象去给成员变量赋值,可以赋值一些非法的数据。
这是不合理的。
应该是这个样子的:在赋值之前,先对数据进行判断。
判断到底在哪里做比较合适呢?
StudentDemo类是一个测试类,测试类一般只创建对象,调用方法。
所以,这个判断应该定义在Student类中。
而我们在成员变量的位置可不可以进行数据判断呢?
是不可以的,因为做数据校验,必须要依靠一些逻辑语句。
逻辑语句是应该定义在方法中的,所以,我们最终决定在Student类中提供一个方法
来对数据进行校验。
按照我们前面的分析,我们给出了一个方法进行校验。
但是呢,它偏偏不调用方法来赋值,还是直接赋值了,
这样我们的方法就没有起到作用。
我就应该要求你必须使用我的方法,而不能直接调用成员变量赋值。
怎么去强制要求不能直接使用成员变量呢?
针对这种情况,Java就提供了一个关键字 private
private:私有的。可以修饰成员变量和成员方法。
注意:被private修饰的成员只能在本类中访问。
其实我讲到现在讲解的是一个封装的思想。
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
*/
private关键字
private关键字:
是一个权限修饰符。
可以修饰成员(成员变量和成员方法)
被private修饰的成员只在本类中才能访问。
private最常见的应用:
把成员变量用private修饰
提供对应的getXxx()/setXxx()方法
一个标准的案例的使用
/*
private:
是一个权限修饰符
可以修饰成员变量和成员方法
被其修饰的成员只能在本类中被访问
*/
class Demo { private int num = 10; public int getNum() { return num; } public void setNum(int a) { if(a < 0 || a > 100){ System.out.println("我是有底线的"); }else{ num = a; } } private void study() { System.out.println("我要学习"); } public void method() { study(); } } class PrivateDemo { public static void main(String[] args) { Demo demo = new Demo(); demo.setNum(120); System.out.println(demo.getNum()); demo.method(); } }
正常Student类测试
/*
封装和private的应用:
A:把成员变量用private修饰
B:提高对应的getXxx()和setXxx()方法
*/
//定义学生类 class Student { //姓名 private String name; //年龄 private int age; //姓名获取值 public String getName() { return name; } //姓名设置值 public void setName(String n) { name = n; } //年龄获取值 public int getAge() { return age; } //年龄赋值 public void setAge(int a) { age = a; } } //测试类 class StudentTest { public static void main(String[] args) { //创建学生对象 Student s = new Student(); //使用成员变量 //错误:被私有修饰了,外界不能直接访问了 //System.out.println(s.name+"---"+s.age); System.out.println(s.getName()+"---"+s.getAge()); //给成员变量赋值 //s.name = "林青霞"; //s.age = 27; //通过方法给赋值 s.setName("林青霞"); s.setAge(27); System.out.println(s.getName()+"---"+s.getAge()); } }
This使用
this:代表所在类的对象引用
记住:
方法被哪个对象调用,this就代表那个对象
什么时候使用this呢?
局部变量隐藏成员变量
其他用法后面和super一起讲解
案例:
/*
我们曾经曰:起名字要做到见名知意。
this:是当前类的对象引用。简单的记,它就代表当前类的一个对象。
注意:谁调用这个方法,在该方法内部的this就代表谁。
this的场景:
解决局部变量隐藏成员变量
*/
class Student { private String name; private String address; private int age; /** 构造方法 */ public Student() { } public Student(String name) { this.name = name; } public Student(String name,int age) { this.name = name; this.age = age; } /** 成员方法,获取name值 */ public String getName() { return name; } } class ConstructDemo { public static void main(String[] args) { Student student = new Student("林青霞"); System.out.println(student.getName()); Student student1 = new Student("林青霞",18); System.out.println(student1.getName()); } }
构造方法
构造方法作用概述
给对象的数据进行初始化
构造方法格式
方法名与类名相同
没有返回值类型,连void都没有
没有具体的返回值
构造方法注意事项
如果你不提供构造方法,系统会给出默认构造方法
如果你提供了构造方法,系统将不再提供
构造方法也是可以重载的
/*
构造方法:
给对象的数据进行初始化
格式:
A:方法名与类名相同
B:没有返回值类型,连void都没有
C:没有具体的返回值
*/
方法构造二
/*
我们一直在使用构造方法,但是,我们确没有定义构造方法,用的是哪里来的呢?
构造方法的注意事项:
A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
给成员变量赋值有两种方式:
A:setXxx()
B:构造方法
*/
类的成员方法
成员方法其实就是我们前面讲过的方法
方法具体划分:
根据返回值
有明确返回值方法
返回void类型的方法
根据形式参数
无参方法
带参方法
案例:
/*
类的组成:成员变量,成员方法
今天我们又加入了一个新的成员:构造方法。
以后再提类的组成:
成员变量
构造方法
成员方法
根据返回值:
void类型
非void类型
形式参数:
空参方法
非空参方法
*/
class Student { public String getString() { return "helloworld"; } public void show() { System.out.println("show"); } public void method(String name) { System.out.println(name); } public String function(String s1,String s2) { return s1+s2; } } class StudentDemo { public static void main(String[] args) { //创建对象 Student s = new Student(); //调用无参无返回值方法 s.show(); //调用无参有返回值方法 String result = s.getString(); System.out.println(result); //调用带参无返回值的方法 s.method("林青霞"); //调用带参带返回值的方法 String result2 = s.function("hello","world"); System.out.println(result2); } }
一个基本类的标准代码写法
类
成员变量
构造方法
无参构造方法
带参构造方法
成员方法
getXxx()
setXxx()
给成员变量赋值的方式
无参构造方法+setXxx()
带参构造方法
一个标准学生代码以及测试:
/*
一个标准代码的最终版。
学生类:
成员变量:
name,age
构造方法:
无参,带两个参
成员方法:
getXxx()/setXxx()
show():输出该类的所有成员变量值
给成员变量赋值:
A:setXxx()方法
B:构造方法
输出成员变量值的方式:
A:通过getXxx()分别获取然后拼接
B:通过调用show()方法搞定
*/
class Student { //姓名 private String name; //年龄 private int age; //构造方法 public Student() { } public Student(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //输出所有的成员变量值 public void show() { System.out.println(name+"---"+age); } } //测试类 class StudentTest { public static void main(String[] args) { //方式1给成员变量赋值 //无参构造+setXxx() Student s1 = new Student(); s1.setName("林青霞"); s1.setAge(27); //输出值 System.out.println(s1.getName()+"---"+s1.getAge()); s1.show(); System.out.println("----------------------------"); //方式2给成员变量赋值 Student s2 = new Student("刘意",30); System.out.println(s2.getName()+"---"+s2.getAge()); s2.show(); } }
Java基础面向对象