一.介绍
面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;这种思想是将数据作为第一位,而方法或者说是算法作为其次,这是对数据一种优化,操作起来更加的方便,简化了过程。
面向对象有三大特征:封装性、继承性、多态性,
(1)封装性指的是隐藏了对象的属性和实现细节,仅对外提供公共的访问方式,这样就隔离了具体的变化,便于使用,提高了复用性和安全性。
(2)继承性,就是两种事物间存在着一定的所属关系,那么继承的类就可以从被继承的类中获得一些属性和方法;这就提高了代码的复用性。继承是作为多态的前提的。
(3)多态是说父类或接口的引用指向了子类对象,这就提高了程序的扩展性,也就是说只要实现或继承了同一个接口或类,那么就可以使用父类中相应的方法,提高程序扩展性,但是多态有一点不好之处在于:父类引用不能访问子类中的成员。
举例来说:就是:比如说你要去饭店吃饭,你只需要饭店,找到饭店的服务员,跟她说你要吃什么,然后就会给你做出来让你吃,你并不需要知道这个饭是怎么错做的,你只需要面向这个服务员,告诉他你要吃什么,然后他也只需要面向你吃完收到钱就好,不需要知道你怎么对这个饭进行吃。
特点:
(1)将复杂的事情简单化。
(2)面向对象将以前的过程中的执行者,变成了指挥者。
(3)面向对象这种思想是符合现在人们思考习惯的一种思想。
(4)面向对象的三大特征:封装,继承、多态
二.知识点介绍
1、面向对象
2、类与对象
3、自定义类练习
4、对象的内存解释
三.上课视频对应说明文档
1、面向对象
1.1、概述
我们回想一下,这几天我们完成一个需求的步骤:首先是搞清楚我们要做什么,然后在分析怎么做,最后我们再代码体现。一步一步去实现,而具体的每一步都需要我们去实现和操作。这些步骤相互调用和协作,完成我们的需求。
在上面的每一个具体步骤中我们都是参与者,并且需要面对具体的每一个步骤和过程,这就是面向过程最直接的体现。
那么什么是面向过程开发呢? 面向过程开发,其实就是面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然后由这些功能方法相互调用,完成需求。面向过程的代表语言:C语言
当需求单一,或者简单时,我们一步一步去操作没问题,并且效率也挺高。 可随着需求的更改,功能的增多,发现需要面对每一个步骤很麻烦了,这时就开始思索,能不能把这些步骤和功能在进行封装,封装时根据不同的功能,进行不同的封装,功能类似的封装在一起。这样结构就清晰了很多。用的时候,找到对应的类就可以了。这就是面向对象的思想。
1.2、特点
(1)是一种更符合我们思想习惯的思想;
(2)可以将复杂的事情简单化;
(3)将我们从执行者变成了指挥者,角色发生了转换;
1.3、举例
买电脑:在买电脑的流程中,我们只关注电脑的性能和价格,而不关心电脑是怎么生产的,如何组装的,此时就是将电脑当作一个对象,而人可以有去购买电脑的操作。
洗衣服:在洗衣服的流程中,我们将衣服和人可以看作为对象,而人可以有洗的动作,衣服则是洗的对象。
1.4、面向对象特性
(1)封装:封装是把对象的属性、操作结合在一起,构成一个独立的对象。一旦封装,内部信息对外界是隐藏的,也就象一个四周密封的房子一样,不允许直接对对象的属性进行操作,要想操作,只能通过局部接口(相当于房子的大门)。外部只能看到对象对操作的反应,而不知道对象是如何做出这一反应的。所以封装包含两个方面的含义,一个是信息隐藏,另一个局部开放。会在接下来的课程中详细学习。
(2)继承:继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。会在接下来的课程中详细学习。
(3)多态:指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。会在接下来的课程中详细学习。
2、类与对象
面向对象的思维方式在Java代码中表现为类的定义与对象的使用。理清类与对象的概念与关系是面向对象的重点。
2.1、类的基本概念
类是具有相同特征(属性)和行为(功能)的一类事物的抽象。
我们将现实事物的特征抽象为类中的成员变量,现实事物的行为功能抽象为类中的成员方法。
注意:实际上所属关系是直接属于类的,均称为成员,如成员变量、成员方法、后边学习的成员内部类,并不单指成员变量。
2.2、类的定义格式
类在Java中代码的体现形式:
(1)使用class(类)来抽象一个现实生活中的事物
(2)定义成员变量对应事物的属性,一般使用private修饰,提供get/set方法
(3)定义成员方法对应事物的功能,一般使用public修饰
定义格式:
public class 类名{
private 数据类型 变量名1;
private 数据类型 变量名2;
…其他成员变量
public 返回值类型 方法名(参数类型 参数名,参数类型 参数名2…){
方法体;
}
每个属性对应的get/set方法,使用this区分成员变量与局部变量
}
如:人类
public class Person {
private String name;
private int age;
public void eat() {
System.out.println(“吃了”);
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge (int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
2.3、类的使用格式
类的使用非常简单,一般分为两个动作:创建对象与调用方法。
类的定义是现实事物的抽象,真正使用的是类创建的对象。通常使用对象来调用方法。
对象创建格式:
数据类型 对象名= new 数据类型();
对象方法的调用:
无返回值:对象名.方法名(参数);
有返回值:返回值类型 变量名 = 对象名.方法名(参数);
2.4、成员变量
直接定义在类中的变量称为成员变量,在面向对象思想设计上,是类的组成部分。
成员变量通常使用private修饰,阻止本类以外的其他类访问。
成员变量不能重名,局部变量不能重名,成员与局部变量可以重名,但是需要使用this区分。
使用this访问的为成员变量,直接访问的为局部。在方法内访问变量,如果没有该名称的局部变量会自动查找是否有该名称的成员变量。
2.5、成员方法
正常定义成员方法时,一般是不需要添加static修饰符的。static修饰符会在后边详细简介。
成员方法一般可分为两类:
(1)没有业务的属性get/set方法,与属性对应
(2)有业务的普通方法,属于类的功能
代码示例:
package cn.javahelp;
/*
* 定义自定义类型 Person类
*
* 属性(成员变量)
* 姓名 String
* 年龄 int
* 行为(成员方法)
* 吃饭
* 睡觉
* 打豆豆
*
* 为成员变量赋值/获取成员变量的值的方法
*
* private 修饰的成员(成员变量,成员方法) 让外界无法直接访问 内部可以访问
*
* this区分成员变量与局部变量(注意:这是定义时所展现出来的功能,其功能本质,一会单独说)
*
* 成员方法 一般不使用static修饰
* 分为两种
* 1.get/set方法
* 2.属于类的功能的方法
*/
public class Person {
//定义成员变量
private String name;
private int age;
private String sex;
//吃饭
public void eat(){
System.out.println(name+"吃了");
}
//睡觉
public void sleep(){
System.out.println(name+"睡了");
}
//打豆豆
public void hitBeanBean(){
System.out.println(name+"打了,爽了,敲代码了!");
}
//为name赋值的方法:方法名:setName;参数:String name;返回值 :void
public void setName(String name){
this.name=name;
}
//获取name的值的方法:方法名;getName;参数:无;返回值:String name
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
package cn.javahelp;
/*
* 测试Person类
*
* 导包 在同一个文件夹下不需要导包
* 创建对象 数据类型 变量名 = new 数据类型()
* 调用方法
* 返回值类型 新变量名 = 变量名.方法名(实际参数);
*
*
* 方法调用时,用static修饰的方法调用其他方法时,其他方法必须使用static修饰
* 指的是
* 在同一个类中,直接调用其他方法时,其他方法必须使用static修饰
* 如果使用对象名.方法名()这种方式 其他方法一般不使用static修饰
*/
public class Test {
public static void main(String[] args) {
//创建对象
Person p= new Person();
//调用方法
p.setName("柳岩");
p.setAge(38);
//因为age用private修饰了 所以外界不能直接访问了
//p.age = -1;
//如果使用对象名.方法名()这种方式 其他方法一般不使用static修饰
p.eat();
p.sleep();
p.hitBeanBean();
String name = p.getName();
System.out.println(name);
System.out.println(p.getAge());
//main方法直接调用method方法 method方法必须使用static修饰
//method();
}
public void method(){
System.out.println("我是一个方法");
}
}
2.6、成员变量和局部变量的区别
(1)在类中的位置不同。成员变量:类中,方法外;局部变量:方法中或者方法声明上(形式参数)
(2)在内存中的位置不同。成员变量:堆内存;局部变量:栈内存
(3)生命周期不同。成员变量:随着对象的创建而存在,随着对象的消失而消失;局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
(4)初始化值的不同。成员变量:有默认值;局部变量:没有默认值。必须先定义,赋值,最后使用
public class DemoVariable {
int x;
public void show() {
int y = 0;
System.out.println(x);
System.out.println(y);
}
}
2.7、类与对象的关系
类是抽象概念,对象是类的具体实例。我们通常真正使用的是某个类的实例对象,进而调用该对象的方法。
一个类可以有多个对象,一个对象只属于一个类(在讲完多态后会有不同的理解)。
可以说创建对象并调用方法是类最主要的使用方式。
我们学习编程语言,就是为了模拟现实世界的事物,实现信息化。比如:去超市买东西的计费系统,去银行办业务的系统。
我们如何表示一个现实世界事物呢:
属性 就是该事物的描述信息
行为 就是该事物能够做什么
举例:学生拥有班级、年纪等属性,拥有上课、考试等行为
我们学习的Java语言最基本单位是类,所以我们就应该把事物用一个类来体现。
类:是一组相关的属性和行为的集合
对象:是该类事物的具体体现
举例:
类 :学生
对象 :小明就是一个对象
2.8、类名作为形式参数和返回值(扩展)
类名作为形式参数案例: 需要的其实是该类的对象
代码示例:
public class Student {
public void study() {
System.out.println("好好学习,天天向上");
}
}
public class Teacher {
public void test(Student s) {
s.study();
}
}
public class Test {
public static void main(String[] args) {
Teacher t = new Teacher();
Student s = new Student();
t.test(s);
}
}
类名作为返回值案例: 返回的其实是该类的对象
public class Student {
public void study() {
System.out.println("好好学习,天天向上");
}
}
public class Teacher {
public Student getStudent() {
Student s = new Student();
return s;
}
}
public class Test {
public static void main(String[] args) {
Teacher t = new Teacher();
Student s = t.getStudent();
s.study();
}
}
3、自定义类练习
在自定义类型基础上,我们可以将现实生活中的任何事物抽象成一个更为完整的类,请自定义并使用一种数据类型。如人类、动物类、汽车类、衣服类、玩具类等
3.1、自定义人类
代码示例:
/*
* 定义自定义类型 Person类
*
* 属性(成员变量)
* 姓名 String
* 年龄 int
* 行为(成员方法)
* 吃饭
* 睡觉
* 打豆豆
*
* 为成员变量赋值/获取成员变量的值的方法
*
* private 修饰的成员(成员变量,成员方法) 让外界无法直接访问 内部可以访问
*
* this区分成员变量与局部变量(注意:这是定义时所展现出来的功能,其功能本质,一会单独说)
*
* 成员方法 一般不使用static修饰
* 分为两种
* 1.get或set方法
* 2.属于类的功能的方法
*/
public class Person {
//定义成员变量
private String name;
private int age;
private String sex;
//吃饭
public void eat(){
System.out.println(name+"吃了");
}
//睡觉
public void sleep(){
System.out.println(name+"睡了");
}
//打豆豆
public void hitBeanBean(){
System.out.println(name+"打了,爽了,敲代码了!");
}
//为name赋值的方法:方法名:setName;参数:String name;返回值:void
public void setName(String name){
this.name=name;
}
//获取name的值的方法:方法名:getName;参数:无;返回值:String name;
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
/*
* 测试Person类
*
* 导包 在同一个文件夹下不需要导包
* 创建对象 数据类型 变量名 = new 数据类型()
* 调用方法
* 返回值类型 新变量名 = 变量名.方法名(实际参数);
*
*
* 方法调用时,用static修饰的方法调用其他方法时,其他方法必须使用static修饰
* 指的是
* 在同一个类中,直接调用其他方法时,其他方法必须使用static修饰
* 如果使用对象名.方法名()这种方式 其他方法一般不使用static修饰
*/
public class Test {
public static void main(String[] args) {
//创建对象
Person p= new Person();
//调用方法
p.setName("柳岩");
p.setAge(38);
//因为age用private修饰了 所以外界不能直接访问了
//p.age = -1;
//如果使用对象名.方法名()这种方式 其他方法一般不使用static修饰
p.eat();
p.sleep();
p.hitBeanBean();
String name = p.getName();
System.out.println(name);
System.out.println(p.getAge());
//main方法直接调用method方法 method方法必须使用static修饰
//method();
}
public void method(){
System.out.println("我是一个方法");
}
}
3.2、自定义car类
代码示例:
/*
* 车类
* 属性
* 颜色
* 品牌
* 价格
* 车牌号
* 车主
* 功能
* 运输货物
* 兜风
* get/set
*/
public class Car {
private String color;//颜色
private String pinPai;//品牌
private double price;//价格
private String number;//车牌号
private String admin;//车主
//运输方法:方法名:yunShu;参数:String货物;返回值:无
public void yunShu(String huoWu){
System.out.println(admin+"开着"+color+pinPai+"价值"+price
+"车牌号为"+number+"的车"+"运输了"+huoWu);
}
//兜风:方法名:douFeng;参数:String name;返回值:无
public void douFeng(String name){
System.out.println(admin+"开着"+color+pinPai+"价值"+price
+"车牌号为"+number+"的车"+"带着"+name+"去兜风");
}
public void setColor(String color){
this.color = color;
}
public String getColor(){
return color;
}
public String getPinPai() {
return pinPai;
}
public void setPinPai(String pinPai) {
this.pinPai = pinPai;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getAdmin() {
return admin;
}
public void setAdmin(String admin) {
this.admin = admin;
}
}
/*
* 测试 自定义类型 车类
*
*/
public class Test {
public static void main(String[] args) {
Car c = new Car();
//调用方法
c.setAdmin("老王");
c.setColor("绿色");
c.setPinPai("三蹦子");
c.setPrice(250.38);
c.setNumber("JP74110");
c.yunShu("猪");
c.douFeng("柳岩");
}
}
3.3、自定义手机类
代码示例:
定义手机类
public class Phone {
//品牌
String brand;
//价格
int price;
//颜色
String color;
//打电话
public void call(String name) {
System.out.println("给"+name+"打电话");
}
//发短信
public void sendMessage() {
System.out.println("群发短信");
}
}
//手机类的测试类
public class Demo02Phone {
public static void main(String[] args) {
//创建对象
Phone p = new Phone();
//输出成员变量值
System.out.println("品牌:"+p.brand);//null
System.out.println("价格:"+p.price);//0
System.out.println("颜色:"+p.color);//null
System.out.println("------------");
//给成员变量赋值
p.brand = "锤子";
p.price = 2999;
p.color = "棕色";
//再次输出成员变量值
System.out.println("品牌:"+p.brand);//锤子
System.out.println("价格:"+p.price);//2999
System.out.println("颜色:"+p.color);//棕色
System.out.println("------------");
//调用成员方法
p.call("唐嫣");
p.sendMessage();
}
}
4、对象的内存解释
对象在内存中的位置:对象由new关键字创建,如同数组,实体存在于堆内存中;任何事物均可以定义成类,创建对象,属于引用类型;而对象的引用变量是一个普通变量。存储的值是该对象堆内存中的地址。
代码示例:
定义Phone类
public class Phone {
String brand;
int price;
String color;
public void call(String name) {
System.out.println("给"+name+"打电话");
}
public void sendMessage() {
System.out.println("群发短信");
}
}
4.1、一个对象的内存图
代码示例:
public class Demo01Phone {
public static void main(String[] args) {
Phone p = new Phone();
System.out.println(p.brand + "---" + p.price
+ "---" + p.color);
p.brand = "锤子";
p.price = 2999;
p.color = "棕色"; System.out.println(p.brand + "---" + p.price
+ "---"+ p.color);
p.call("林青霞");
p.sendMessage();
}
}
4.2、两个对象,使用同一个方法的内存图
代码示例:
public class Demo02Phone {
public static void main(String[] args) {
Phone p1 = new Phone();
p1.brand = "小米5s";
p1.price = 1999;
p1.color = "银色";
System.out.println(p1.brand+"---"+p1.price+"---"+p1.color;
p1.call("林青霞");
p1.sendMessage();
Phone p2 = new Phone();
p2.brand = "IPhone7S";
p2.price = 7999;
p2.color = "土豪金";
System.out.println(p2.brand+"---"+p2.price+
"---"+p2.color);
p2.call("张曼玉");
p2.sendMessage();
}
}
4.3、两个引用,指向同一个对象的内存图
代码示例:
public class Demo03Phone {
public static void main(String[] args) {
Phone p1 = new Phone();
p1.brand = "OPPO";
p1.price = 2999;
p1.color = "白色";
System.out.println(p1.brand+"---"+p1.price
+"---"+p1.color);
Phone p2 = p1;
p2.brand = "魅族";
p2.price = 1999;
p2.color = "蓝色";
System.out.println(p1.brand+"---"+p1.price+"---"+p1.color);
System.out.println(p2.brand+"---"+p2.price+"---"+p2.color);
}
}