Java基础教程【第六章:面向对象】

振华OPPO 发表于 2022/04/22 15:13:20 2022/04/22
【摘要】 @TOC 1. 面向对象简介面向对象作为一种思想及编程语言,为软件开发的整个过程:从分析设计到实现,提供了一个完整解决方案。面向对象堪称是软件发展取得的里程碑式的伟大成就。从 80 年代后期开始,进行了面向对象分析(OOA)、面向对象设计(OOD)和面向对象程序设计(OOP)等新的系统开发方式模型的研究。类与对象的概念:对象:现实世界中每个事务都是一个对象;即某一个类型事务的实例。类:对象的...

@TOC

1. 面向对象简介

面向对象作为一种思想及编程语言,为软件开发的整个过程:从分析设计到实现,提供了一个完整解决方案。面向对象堪称是软件发展取得的里程碑式的伟大成就。

从 80 年代后期开始,进行了面向对象分析(OOA)、面向对象设计(OOD)和面向对象程序设计(OOP)等新的系统开发方式模型的研究。

类与对象的概念:
对象:现实世界中每个事务都是一个对象;即某一个类型事务的实例。
类:对象的抽象称之为类、分类、类型、模型。

在这里插入图片描述

2. 面向对象的方法实现抽象

在这里插入图片描述
抽象:就是抽取,提取。
PS:如比说人,这是一个相对抽象的概念,抽象的概念一般是指某一类事物,而不是某一个事物。而对象是一个具体的概念,一个具体的人具有性别、年龄、身高及技能操作等具体特征。
而抽象的“人“不具有这些特征,具体的人是指比如说张三、李四等等。

3. 类与对象,消息与方法

3.1 OOP中的类

1.类实质上定义的是一种对象类型,它是对具有相似属性行为的对象的一种抽象。
2.描述了属于该类型的对象的性质——统一的属性和操作方式。
3.属性是指描述对象的一组数据,表现为对象的一些变量。
4.操作代码或方法表示对象的行为或所作的工作。

==总结:类,是创建对象的模板。==

3.2 类的属性

是指描述对象的一组数据,代码中的具体表现形式为变量。

在这里插入图片描述

3.3 类的方法

操作代码或方法表示对象的行为或所作的工作。
在这里插入图片描述

在这里插入图片描述

3.4 消息与方法

对象是类的实例。尽管对象的表示在形式上与一般数据类型十分相似,但是它们之间存在一种本质区别:
对象之间通过消息传递方式进行通信。 消息传递原是一种与通信有关的概念,OOP 使得对象具有交互能力的主要模型就是消息传递模型。
对象被看成用传递消息的方式互相联系的通信实体,它们既可以接收可以拒绝外界发来的消息。一般情况下,对象接收它能够识别的消息,拒绝它不能识别消息。
对于一个对象而言,任何外部的代码都不能以任何不可预知或事先不允许的方式与这个对象进行交互。
发送一条消息至少应给出一个对象的名字和要发给这个对象的那条消息的名字。经常,消息的名字就是这个对象中外界可知的某个方法的名字。在消息中,经常还有一组数(也就是那个方法所要求的参数),将外界的有关信息传给这个对象。

PS:老师有教书的方法,那么老师可以通过教的方法将知识传输给学生,那么学生需要有学习的方法。通过学习的方法来接受知识。如下列代码:

public class Teacher {
void teach(String content) {
System.out.println("开始传授" + content + "...");
Student stu = new Student();
stu.study(content);
}
public static void main(String[] args) {
Teacher t = new Teacher();
t.teach("java");
} }

定义类的语法:

class 类的名称{ 
	[访问修饰符] 数据类型 属性名; //声明成员变量
	...
	[访问修饰符] 返回值类型 方法名([参数列表]) {
		程序代码语句;
		return 值或表达式;
	 } 
}

成员变量的定义:又叫实例变量,定义在类中,方法外的变量叫做成员变量,属于某一个对象。
成员方法:又叫实例方法,必须通过某个对象来进行访问调用。
语法说明:[ ]中的内容可有可无。

3.5 语法规则

1、访问修饰符有 4 种:(在后面访问修饰符的时候详细说明)
a) public:公共的;
b) 不写:默认的;
c) protected:受保护的;
d) private:私有的;
PS:目前一般写成是 public 或者不写。

2、数据类型:包含基本数据类型和引用数据类型
3、属性名、方法名:同变量的定义规则;
4、 返回值类型:
a) 没有返回值使用 void;
b) 有返回值可以是基本数据类型或者引用数据类型
5、参数列表:包含参数的类型,个数,顺序。
6、 程序代码:顺序结构、分支语句、循环语句;
7、return:只有当方法有返回值的时候才需要,值或表达式结果的类型必须和返回值类型相同或者它的小类型。

//没有返回值没有传参
void eat(){
System.out.println("eat");
}
//没有返回值有传参
void eat(String str,int a){
System.out.println("eat");
}
//有返回值有传参
int eat(String str,int a){
System.out.println("eat");
return 100;//换成(byte)100;
}

访问类中的属性和方法:如果需要去访问类中的属性和方法,则需要先创建该类的对象。

调用属性:对象名.属性名;
调用方法:对象名.方法名(参数列表);

public class Person {
String name; // 定义属性,人的姓名
int age; // 定义属性,人的年龄
/**
* 定义方法,显示人的姓名和年龄
*/
public void show() {
// +和字符串一起使用的时候表示连接而非加分运算
System.out.println("姓名:" + name + ",年龄:" + age);
}
public static void main(String[] args) {
Person person = new Person(); // 创建人的对象,即某一个成员
person.name = "jack"; // 初始化人的姓名,通过赋值=将jack赋值给该对象的姓名属性
person.age = 34; // 初始化人的年龄,通过赋值=将34赋值给该对象的年龄属性
person.show(); // 调用show()方法
} }

PS:通过对象调用属性和方法,可以在同一个类的 main 方法中调用,也可以在不同的类中进行调用。

3.6 内存的划分

内存的操作,为属性赋值:

在这里插入图片描述
PS:栈空间保存的是基本数据类型和字符串,包括局部变量的引用,堆空间保存的动态产生的数据,比如 new 创建出来的对象,也就是引用数据类型。上面两个 Person 实例在堆空间开辟了两块内存,那么相互之间进行调用的时候就不会受到影响,只要使用了 new 关键字,必会在堆空间开辟内存。

4. 构造函数,方法的重载

4.1 定义

要使用面向对象,首先必须构造对象,并指定它们的初始状态,然后通过对象调用方法。在 java 的语言设计中,使用构造函数(constructor)来构造新的实例,一个构造函数是新的方法,它的作用就是构造对象并进行初始化。

4.2 特点

(1)构造函数的方法名与类名相同。
(2)构造函数没有返回类型。
(3)构造函数的主要作用是完成对类对象的初始化工作。
(4)构造函数不能由编程人员显式地直接调用。
(5)在创建一个类的新对象的同时,系统会自动调用该类的构造函数为新对象初始化。

public class Person {
String name;
int age;
//要使用Person的方法,必须先创建Person类的对象,在创建对象的同时对name,age属性进行了初始化
public Person(String name, int age) {
super();
this.name = name;
this.age = age; } }

4.3 作用

(1)对象初始化
(2)引入更多的灵活度(变量赋值或更复杂的操作)
(3)Java 中可以不定义构造函数
Java 中可以不定义构造函数,此时系统会自动为该系统生成一个默认的构造函数。这个构造函数的名字与类名相同,它没有任何形式参数,也不完成任何操作。 为了避免失去控制,一般将构造函数的声明与创建分开处理。

4.4 构造函数重载

一个类可以有多个构造函数,如果一个类没有定义一个构造函数,Java 编译器将为这个类自动提供缺省构造函数(即无参的构造函数) ,缺省构造函数将成员变量的值初始化为缺省值,一旦创建了自己的构造函数, Java 编译器将不再自动提供无参的构造函数。
重载构造函数提供了一组创建对象的方式,可以根据需要决定是否带初始参数。根据参数列表决定调用的是哪个重载的构造函数。
构造函数重载:一个类中可以有多个构造函数,它们具有不同的参数列表(参数的类型、个数、顺序)

public class Person {
	String name;
	int age;
	public Person() {
	System.out.println("无参的构造函数");
	}
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
		System.out.println("带两个参数的构造函数1");
	}
	public Person(int age, String name) {
		this.name = name;
		this.age = age;
		System.out.println("带两个参数的构造函数2");
	}
	public Person(String name) {
		this.name = name;
		System.out.println("参数为name的构造函数");
	}
	public Person(int age) {
		this.age = age;
		System.out.println("参数为age的构造函数");
	} 
}

this 关键字:与对象关联,表示当前对象(实例),即 new 出的是哪个对象,代表的就是哪个对象。this 关键字的作用:可以调用调用类中的构造方法,普通方法,成员变量。this 调用构造方法只能是在构造方法中使用,必须是第一行。

public class Person {
String name;
int age;
public Person() {
this("jack");//如果使用this调用构造方法,必须在第一行,只能在构造方法种调用构造方法。
System.out.println("无参的构造函数");
this.show();
}
public Person(String name) {
this(20);
System.out.println("参数为name的构造函数");
}
public Person(int age) {
System.out.println("参数为age的构造函数");
}
public void show(){
//this(); //不可调用。
System.out.println("show");
}
public static void main(String[] args) {
new Person();
}
}

方法重载:方法重载是 java 中实现面向对象多态性机制的一种方式。
同一个类中多个方法有相同的名字,不同的参数列表(参数的个数,类型,顺序),和返回值类型无关,这种情况称为方法重载。
当重载方法被调用时,Java 编译器根据参数的类型、数量、顺序来确定实际调用哪个重载方法的版本。方法重载不考虑方法的返回类型。

5. 封装

a)封装是对象的一种隐藏技术,其目的是将对象中的属性和方法组织起来。同时隐藏不想暴露的属性和方法及实现细节。
b)用户或其它对象不能看到也无法修改其实现。只能通过接口去调用对象的方法,达到互相通信的目的。
c)封闭的目的在于将设计者与使用者分开。使用者不必知道实现的细节,只需用设计者提供的方法来访问该对象。

public class DrawImage {
private int weight;
private int height;
public void setHeight(int height) {
if (height > 100)
System.out.println("高度不能高于100");
else
this.height = height; }
public int getHeight() {
return height; }
public void setWeight(int weight) {
if (weight > 200)
System.out.println("宽度不能大于200");
else
this.weight = weight; }
public int getWeight() {
return weight; }
public void draw() {
drawLine();
drawPoint();
System.out.println("你画了一幅画");
}
private void drawPoint() {
System.out.println("画了一个点");
}
private void drawLine() {
System.out.println("画了一条线");
} }

6. 继承,抽象,方法重写

继承是面向对象编程技术的一块基石,它允许创建分等级层次的类。运用继承,可以创建一个通用类定义一系列一般特性。该类可以被更具体的类继承。
(1)被继承的类称为父类或者超类或者基类
(2)继承父类的类称为子类或者派生类
(3)执行继承时,子类将获得父类的所有成员(包括 private 的成员,私有的不能直接访问),并具有自身特有的属性。

==super 关键字:==
super 是一个引用,专门用来在子类中访问父类中的构造函数、方法和实例变量。
1.使用 super 在子类的构造函数中调用父类的构造函数,语法:
super()或者 super(参数列表)
super()必须是在子类构造函数中的第一个执行语句。

2.在子类的方法中调用父类中的方法,语法:
super.方法名(参数列表)

3.在子类的方法中调用父类中的实例变量, 语法:
super.实例变量名

继承总结:
1、 子类继承父类,继承了父类的所有属性和方法(包含私有的),私有的不能直接访问;
2、一个类如果没有使用 extends,那么它将继承 Object 类,Object 类是所有类的父类,始祖类;
3、一个类可以继承多个类,但 java 中规定一个类只能直接继承一个类;可以间接继承;
4、子类具有扩展的功能,扩展子类特有的属性和方法;
5、继承大大提供了代码的重复利用性

方法重写(覆盖)override:是 java 实现多态机制的另外一种形式。
在不同类中,如果子类中的一个方法与父类中的方法有相同的返回类型、相同的方法名并具有相同数量和类型的参数列表,这种情况称为方法覆盖。
当一个覆盖方法通过父类引用被调用,Java 根据当前被引用对象的实际类型来决定执行哪个版本的方法。
可以通过 super 关键字调用直属父类中被覆盖的方法版本。

//方法重写示例:
public class Father {
public String say(){
return "我是父类"; } }
public class Son extends Father {
@Override
public String say() {
// super.say();//当创建的是子类对象的时候,如果需要调用父类的方法可以使用super关键字
return "我是儿子类"; } }
public class Daughter extends Father{
@Override
public String say() {
return "我是女儿类"; } }
public class Test {
public static void main(String[] args) {
Father f = new Father();
f.say();// 创建的是父类对象,调用的是是父类方法
Father s = new Son();
s.say();// 创建的是儿子类对象,调用的是儿子类方法
Father dau = new Daughter();
dau.say();// 创建的是女儿类对象,调用的是女儿类的方法
} 
}

抽象类:
定义:一种类型,只提供部分方法的具体实现。
语法:abstract class 类名{
….
}

一般情况下,抽象类既包含具体方法,又包含抽象方法。
具体方法:既有方法的声明,又有方法的实现(即有方法体)。
抽象方法:只有方法的声明,而没有方法的实现(即没有方法体)。
语法:abstract 返回类型 方法名(参数列表)

//抽象类的示例:
public abstract class Father {
String name;
int age;
public Father() {
}
public Father(String name, int age) {
this.name = name;
this.age = age; }
public abstract void say();// 抽象方法,没有方法体
public void see() {
System.out.println("see");
} }
public class Son extends Father {
public Son() {
}
public Son(String name, int age) {
super(name, age);
}
// 必须要重写父类的所有抽象方法,包含间接父类
@Override
public void say() {
System.out.println("我必须要重写父类的所有抽象方法");
} }
public class Test {
public static void main(String[] args) {
Father f = new Son();//抽象类不能被实例化,必须通过子类进行实例化
f.say();
} 
}

==总结:==
抽象类不能被实例化。
抽象类就是用来继承的。
子类必须为抽象类中的所有抽象方法提供具体实现,否则,子类也将是一个抽象类。
抽象类中可以声明实例变量,这些实例变量就是为了提供给子类继承的。
抽象类可以有一个或多个构造函数,它是提供给子类进行调用的。
特别地,抽象类中的所有方法都可以是具体方法。

7. 多态

多态和动态绑定:
声明类型:对象变量被声明时的类型
实际类型:对象变量实际指向的对象类型
一个对象变量可以指向多种实际类型的现象称为“多态”
在运行时自动选择正确的方法进行调用的现象称为“动态绑定”
Java 根据对象的实际类型来进行方法调用
==编译时多态:编译时动态重载.(方法重载) ==
==运行时多态:指一个对象可以具有多个类型。 (方法重写)==

//多态示例 1:
public class Test {
public void add(int a, int b) {
}
public void add(short a, short b) {
} }
//多态示例 2:
public abstract class Father {
public abstract void say();
}
public class Son extends Father {
@Override
public void say() {
System.out.println("Son is say");
}
public void play() {
System.out.println("Son is play");
} }
public class Daughter extends Father {
@Override
public void say() {
System.out.println("Daughter is say");
}
public void sing() {
System.out.println("Daughter is sing");
} }
public class Test {
public static void main(String[] args) {
Father f = new Son();
f.say();
// instanceof判断一个对象是否属于一个类,必须有继承关系
if (f instanceof Son) {
((Son) f).play();//
}f = new Daughter();
f.say();
if (f instanceof Daughter) {
((Daughter) f).sing();
} 
} 
}

总结:运行时多态的三大前提条件
1.要有继承
2.要有方法的重写
3.父类引用指向子类对象(对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接)

8. 设计模式之工厂模式

通过工厂方法模式,提高了程序的可维护性和可扩展性。

若诸世界六道众生,其心不淫,则不随其生死相续。汝修三昧,本出尘劳。淫心不除,尘不可出。纵有多智禅定现前,若不断淫,必落魔道。--《楞严经》

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。