Java学习笔记_10 面向对象:封装、继承、多态

本文介绍了面向对象的思想,对比了面向过程和面向对象的区别,并详细讲解了面向对象的三大特征——封装、继承和多态。通过实例展示了如何在Java中实现封装,如何使用继承创建类的层次结构,以及多态的概念和实现方式,包括重载和重写。文章还提供了代码示例以加深理解。
摘要由CSDN通过智能技术生成

本文知识点:
面向对象的思想。
面向对象的特征:封装、继承、多态。

首先,面向对象是一种思想。

相对于面向过程而言。

举个例子,你在淘宝买东西。

看好物品后,点击购买,

面向过程的思想:想一下用什么减震材料把物品给包装好,通过什么物流走哪条路线安排哪辆车,安排哪个快递员配送。(强调行为、动作、过程)
面向对象的思想:物品包装、物品物流、物品配送。(强调具备了功能的对象)

不管是包装物品,物流物品还是配送物品。操作的都是物品这个对象。所以只需要将所有功能都定义在物品这个对象上,物品就具备了包装、物流、配送的全部功能 。

不难看出,面向对象(买东西),我只需要对物品进行操作。调用封装好的方法:如何把物品给包装好;通过什么物流用哪辆车走哪条路线;安排哪个快递员配送。

即可。

面向对象这种思想,能让复杂问题简单化,我们不需要了解具体的实现过程,只需要指挥对象去实现功能。

基于这些方法已经实现了(封装好了)的基础上。我们只需要调用这些封装好的方法即可,不需要想着怎么去实现它。

所以说,面向过程是面向对象的基础。

在这里插入图片描述

面向对象的特征:封装、继承、多态

封装

所谓封装,就是将方法的过程和数据打包起来,形成一个整体。并尽可能隐藏其内部实现细节的一种方法。

如何实现?

通过关键字private,protected和public实现封装。前面的笔记提到过这些关键字,他们修饰的属性具有不同的访问数据范围的能力。例如,实体类中的属性要私有化,就是用private来修饰。
在这里插入图片描述

如何访问?

对数据的访问只能通过已定义的接口:添加set get 方法。(通过set get方法来访问其属性)

快速创建set get的小技巧:

右键 -> source -> Generate Getters and Setters
在这里插入图片描述
选择需要的勾上就完事儿了。
在这里插入图片描述

public class Book {
	private String author;//实例变量
	static String s1; //类变量
	private String name;
	private int price;


	public Book(){
		
	}
	
	public Book(String author, String name, int price) {
		super();
		this.author = author;//使用this是为了解决实例变量和此处局部变量命名冲突的问题。(Java类的两种成员变量:一种没有 static 修饰,为实例变量;一另种是被static关键字修饰的变量,叫类变量或者静态变量。所以实例变量属于成员变量。)
		this.name = name;
		this.price = price;
	}
	
	public String getAuthor() {//访问author
		return author;
	}
	
	public void setAuthor(String author) {//给author赋值
		this.author = author;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getPrice() {
		return price;
	}
	
	public void setPrice(int price) {
		this.price = price;
	}

}


调用一下:

public class Test {
	public static void main(String[] args) {
		Book book = new Book("张三","Java编程思想",85);
		book.setAuthor("Huey");//重新设置作者
		System.out.println(book.getAuthor());
	}
}

运行结果:

Huey

继承

继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。

类的出现,增强了代码的可复用性,可以大大缩短开发周期。

举个例子,定义了一个类叫。树的属性有:树根、树干、树叶。又由这个树可以派生出两个子类:松树、柿子树。这就是子类的继承。

继承关键字:extends
子类 继承 父类:Son extends Father
子类可以继承(拥有)父类可被继承的功能和属性(私有化除外)。
同时还可以创建自己的功能和属性。
注意:一个类只能继承一个父类。
在Java当中,继承关系是单继承关系。
Object是所有类的父类。(顶级父类)//默认继承

多态

是同一个行为具有不同表现形式的能力。(同一种事物的不同表现形式),多体现在方法上面。

经典面试题:⭐️⭐️⭐️⭐️⭐️

实现多态的两种机制是什么?并分别进行解释说明。

重载和重写
重载:在同一个类当中,方法名相同,参数列表不同,叫做重载。(参数列表遵循就近原则)
重写(覆盖):在继承关系当中,方法签名相同(方法名和参数列表都相同),方法体不同,叫做重写。

关于重写的一个小Demo:

Father:

package day11_6;

public class Father {
	int age = 40;
	String name;
	
	public void test(){
		String message = "父类的方法";
		System.out.println(message);
	}
}

Son:

package day11_6;

public class Son extends Father {
	int age = 18;
	
	public void test(){
		System.out.println("这是子类的方法");
	}
}

Test

package day11_6;

public class Test {
	public static void main(String[] args) {
		//创建一个子类的对象,叫son
		Son son = new Son();
		//测试:输出对象son的age的值
		System.out.println(son.age);//就近原则,优先使用子类自己的
		son.test();//覆盖掉父类的了,父类不满足子类的需求 
	}
}

运行结果:

18
这是子类的方法

综合小Demo:

Book.java

package day11_4;

/**
 * @author Huey
 * @date 2020-11-4
 * 标准实体类的写法
 * 注意:1、实体类中的属性要私有化,就是用private来修饰
 * 		2、无参构造方法
 * 		3、有参构造方法
 * 		4、添加set get 方法(通过set/get方法来访问其属性)
 */
public class Book {
	private String author;
	private String name;
	private int price;


	public Book(){
		
	}
	
	public Book(String author, String name, int price) {
		super();
		this.author = author;
		this.name = name;
		this.price = price;
	}
	
	public String getAuthor() {
		return author;
	}
	
	public void setAuthor(String author) {
		this.author = author;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getPrice() {
		return price;
	}
	
	public void setPrice(int price) {
		this.price = price;
	}

}

父类Person:

package day11_4;

/**
 * @author Huey
 * @date 2020-11-4
 * 
 */
public class Person {//人这个类型:Person 人->特征
	String name;//
	int age;
	String address;
	int IdCard;
	public  Person(){
		System.out.println("这是无参构造方法");
	}
	public  Person(String name,int age,String address,int IdCard){//有参构造(传值)
		this.name = name;
		this.age = age;
		this.address = address;
		this.IdCard = IdCard;
		System.out.println("这是有参构造方法1");
	}	
	public Person(String name, int age, String address) {
		this.name = name;
		this.age = age;
		this.address = address;
		System.out.println("这是有参构造方法2");
	}
	public Person(String name, int age) {
		this("李四",30,"宿迁");
		this.name = name;
		this.age = age;
		System.out.println("这是有参构造方法3");
	}
	
	
}

子类Student继承父类Person:

package day11_4;

public class Student extends Person{
	String StuID;
	
	public void study(){
		System.out.println("当前工作内容:学习");
	}
}

子类继承父类的所有特征(name、age、address…)包括方法等,而父类(Person)则不会包含子类(Student)中的特征,如StuID。

测试:

package day11_4;

/**
 * @author Huey
 * @date 2020-11-4
 * 
 */
public class Test {
	public static void main(String[] args) {
		Person p = new Person("张三",35);//里面的许多操作被封装了。ex.电脑开机
		Book book = new Book("张三","Java编程思想",85);
		book.setAuthor("李四");
		System.out.println(book.getAuthor());
		Student stu = new Student();
		stu.age = 18;
		stu.StuID = "12";
	}
}

运行结果:

这是有参构造方法2
这是有参构造方法3
李四
这是无参构造方法

由于在这里插入图片描述
这里的this(“李四”,30,“宿迁”)起到了调用本类中其他构造方法的作用。也就是调用了有参构造2里的构造方法,所以会输出:

这是有参构造方法2
这是有参构造方法3


在这里插入图片描述
这行代码调用Student的构造方法为其赋值,由于继承关系,所以默认在子类的构造方法的第一行有默认的super();所以默认先调用了父类的构造方法。

而此例,子类并无构造方法,故而直接调用父类的构造方法为其赋值。父类的构造方法如下:
在这里插入图片描述

综合实战:选择题系统

Question:

package day11_6;

/**
 * @author Huey
 * @date 2020-11-6
 * 选择题:父类
 * 		题干:
 * 		选项
 * 
 */
public class Question {
	String title;//题干
	String [] choices;//选项
	char [] answers;//输入的答案
	
	//检测
	public boolean check(char[] answers) {
		return false;
	}	
}

SingleQuestion:

package day11_6;

/**
 * @author Huey
 * @date 2020-11-6
 * 单选题
 * 
 */
public class SingleQuestion extends Question {
	char answer;//标准答案
	
	public boolean check(char[] answers){
		if(answers[0] == answer){//若比较字符串则用if(answers[0].equals("A"))
			return true;
		}else{
			return false;
		}
	}
}

QuestionTest:

package day11_6;

import java.util.Scanner;

public class QuestionTest {
	public static void main(String[] args) {
		SingleQuestion single = new SingleQuestion();
		single.title = "1.谁比黄旭还猛()?^_^";
		single.choices = new String[]{"A.Huey","B.Gai","C.Will","D.Gali"};
		System.out.println(single.title);
		
		for(int i = 0;i<single.choices.length;i++){
			System.out.print(single.choices[i]+"  ");
		}
		
		System.out.println("\n请输入答案:");
		Scanner scanner = new Scanner(System.in);
		String answer = scanner.next();
		//将字符串转换成字符数组char[]
		char [] answers = answer.toCharArray();
		single.answer = 'A';
		
		boolean flag = single.check(answers);//check方法,检测是否正确返回布尔类型
		if(flag){  
			System.out.println("回答正确");
		}else{
			System.out.println("回答错误");
		}
	}
}

运行结果:

1.谁比黄旭还猛()?^_^
A.Huey  B.Gai  C.Will  D.Gali  
请输入答案:
A
回答正确


个人学习笔记,若有误还望不吝赐教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值