java小白训练营2109-day06-OOP:面向对象+封装+继承+多态

面向对象

面向过程和面向对象的区别?

编程思想
面向过程:关注完成一个需求,代码实现步骤,每一步都完成,整个需求就实现。
面向对象:关注实体 entity,特征(属性)+行为(方法),建模(建立模型),然后在一步步的实现(步骤)

案例:把大象装入冰箱

面向过程思考的方式:步骤
第一步:把冰箱门打开,
第二步:把大象放入,
第三步:把冰箱门关上
(步骤)
面向对象思考的方式:实体+步骤
实体(从描述中挑名称)大象和冰箱
大象:特征(巨大、鼻子长、很重、…)行为(吃、跑、洗澡…)
冰箱:特征(门、电、容积…)行为(制冷、存储、开门、关门…)
(步骤)

案例:我去超市买葡萄、水饺、薯片、香蕉

面向过程:
第一步:出门,去超市
第二步:找葡萄、找水饺,买
第三步:回家
面向对象:
实体:葡萄、水饺、超市的所有商品!!!!!(香蕉、包子、薯片)
第一步:出门,去超市
第二步:找葡萄、找水饺、薯片、香蕉,买
第三步:回家

需求变更,(用户)
用户至上!ipad
实际开发,半面向对象,半面向过程,结合来实现具体的代码

面向对象的三大特征

封装、继承、多态、(抽象)
在这里插入图片描述

封装 encapsulation

作用:包装,不能看到它的内部结构,也不能了解其内部运行机制。封装后,好处使用起来简单,不需要知道它运行机制,照样使用。隐藏起来,让使用者更加方便简易。
String api ,这些方法你知道它怎么实现吗? 日常使用者是不知道的,也不需要知道。日常开发者知道其特性,能正确使用即可。toUpperCase() 特性外在表现,大写。
包装类型,它是引用类型,打印时不是,重写了toString方法,重写了hashcode(特殊处理)

封装案例,实体对象

Person实体
1)私有属性 private,对应每个私有属性
2)两个方法 getName() 获取,setName() 设置(eclipse直接自动生成)
上面的过程,私有是属性,它无法直接进行访问,必须通过新的get和set进行访问,特别是set
p.name =“tony”;
p.setName(“tony”);
setName内部在干什么,调用者它是不知道的,这个就是封装,隐藏实现细节。

package cn.tedu.entity;

/*
 * 实体类:
 * 1)一堆私有属性,见名知意
 * 2)每个属性都有get和set方法
 */
public class Person {
	private String name;	//姓名
	private Double money;	//薪水
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		//name参数
		//this.name 属性,成员变量 this代表当前类
		this.name = name;
	}
	
	public Double getMoney() {
		return money;
	}
	public void setMoney(Double money) {
		this.money = money;
	}
}

package cn.tedu.entity;

/*
 * 实体类:
 * 1)一堆私有属性,见名知意
 * 2)每个属性都有get和set方法
 * 3)不是必要,测试(调试)toString()
 */
public class Person {
	private String name;	//姓名
	private Double money;	//薪水
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public Double getMoney() {
		return money;
	}
	public void setMoney(Double money) {
		this.money = money;
	}
	
	@Override //注解,重写,覆盖父类Object.toString()方法
	public String toString() {
		return "Person [name=" + name + ", money=" + money + "]";
	}
}


package test;

import org.junit.Test;
import cn.tedu.entity.Person;

public class TestPerson {
	@Test
	public void person() {
		//1. 创建对象实例
		Person person = new Person();
		
		//2. 设置属性值
		person.setName("陈晨");
		person.setMoney(10000.0);
		
		//3. 获取属性值进行打印
		System.out.println(person.getName());
		System.out.println(person.getMoney());
		
		//4. 打印对象不是地址,而是想打印它的所有的内容
		System.out.println(person); 
		//打印对象实质是调用对象的toString方法,如果对象没有写这个方法,它会调用父类的toString();
		//为什么它不调用父类的方法,而调用自己的方法呢? 方法名相同是调用原则:就近原则
		System.out.println(person.toString());
	}
}


利用eclipse 自动生成get和set方法,以及toString()方法

在这里插入图片描述

在这里插入图片描述

继承 inheritance

在这里插入图片描述

java中继承和其他语言不同的,它提供两种方式
1)继承 extends 只能单继承,安全性高不易出错
2)实现 implements 可以实现多个接口,它的类也称为实现类

为什么需要类继承?

继承的好处是,可以减少相同的代码(冗余),当需要变化时,只需修改一处,所以调用的地方就都更新了。

package cn.tedu.entity;

//水果类
public class Fruit {
	public void eat() {
		System.out.println("水果可以吃");
	}
}


package cn.tedu.entity;

//苹果类,继承父类,父类的公用的方法就直接可以调用
public class Apple extends Fruit{
}

package cn.tedu.entity;

//梨类,代码冗余了?
public class Pear extends Fruit{
}

接口的实现方式

需求:
动物,老虎和兔子,他们都吃东西(共性)老虎吃肉肉,兔子吃草草

package cn.tedu.entity;

//接口,定规矩,定要求
//所有的类都得实现eat()方法
public interface Animal {
	//不实现,只定规矩
	//这里只定义规矩,子类去实现具体的代码
	public void eat(); //这里只是一个方法的定义,没有方式的实现代码
}


package cn.tedu.entity;

//老虎实现类
public class Tiger implements Animal{
	@Override
	public void eat() {
		System.out.println("老虎吃肉肉");
	}
}

package cn.tedu.entity;

//兔子实现类,遵守规矩,implements 接口
//它必须实现Animal接口中定义方法,必须写类的实现的代码
//The type Rabbit must implement 
//the inherited abstract method Animal.eat()
public class Rabbit implements Animal{
	@Override //覆盖,重写,有没有都可以,它是提示你覆盖父类的方法
	public void eat() {
		System.out.println("兔子吃草草");
	}
}


package test;

import org.junit.Test;

import cn.tedu.entity.Animal;
import cn.tedu.entity.Apple;
import cn.tedu.entity.Rabbit;
import cn.tedu.entity.Tiger;

public class TestAnimal {
	@Test
	public void animal() {
		//类的写法
		//格式:类名 实例名 = new 类名();
		Apple apple = new Apple();
		//接口的写法
		//格式:接口名称 实例名称 = new 实现类名称();
		//Cannot instantiate the type Animal 接口animal是不能实例化
		//Animal tiger = new Animal();
		Animal tiger = new Tiger();
		tiger.eat();
		
		Animal rabbit = new Rabbit();
		rabbit.eat();
	}
}




两种继承方式比较

在这里插入图片描述

多态 polymorphism

需求:人Person,喂小动物 feed( who )
现在有:老虎,兔子
person.feed(老虎)
person.feed(兔子)
需求变更:狗、猫
person.feed(狗)
person.feed(猫)
增不能写个通用的,代码量急剧降低,如果在有新的动物,person.feed(new)
person.feed(Animal)

package cn.tedu.entity;

/*
 * 实体类:
 * 1)一堆私有属性,见名知意
 * 2)每个属性都有get和set方法
 * 3)不是必要,测试(调试)toString()
 */
public class Person {
	private String name;	//姓名
	private Double money;	//薪水
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public Double getMoney() {
		return money;
	}
	public void setMoney(Double money) {
		this.money = money;
	}
	
	@Override //注解,重写,覆盖父类Object.toString()方法
	public String toString() {
		return "Person [name=" + name + ", money=" + money + "]";
	}
	
	//不通用的方式,有几个动物就得写多个个代码,代码量非常的大
	//喂老虎
	public void eat(Tiger tiger) {
		tiger.eat();
	}
	
	//喂兔子
	public void eat(Rabbit rabbit) {
		rabbit.eat();
	}
	
	//通用的结构,使用接口作为参数
	//如果有新的动物扩充,此时这里的代码无需修改
	public void eat(Animal animal) {
		//它的参数不能是接口,但是接口的子类
		//实现类,实现类中写了具体代码
		animal.eat();
	}
}


package cn.tedu.entity;

//猫类,实现Animal它的接口,必须实现Animal定义的所有的方法
public class Cat implements Animal{
	@Override
	public void eat() { //遵循Animal定义eat方法,守规矩
		System.out.println("猫吃小鱼");
	}

}


package test;

import org.junit.Test;

import cn.tedu.entity.Animal;
import cn.tedu.entity.Cat;
import cn.tedu.entity.Person;
import cn.tedu.entity.Rabbit;
import cn.tedu.entity.Tiger;

public class TestPerson {
	@Test
	public void person() {
		//1. 创建对象实例
		Person person = new Person();
		
		//2. 设置属性值
		person.setName("陈晨");
		person.setMoney(10000.0);
		
		//3. 获取属性值进行打印
		System.out.println(person.getName());
		System.out.println(person.getMoney());
		
		//4. 打印对象不是地址,而是想打印它的所有的内容
		System.out.println(person); 
		//打印对象实质是调用对象的toString方法,如果对象没有写这个方法,它会调用父类的toString();
		//为什么它不调用父类的方法,而调用自己的方法呢? 方法名相同是调用原则:就近原则
		System.out.println(person.toString());
		
		//不通用的方式的调用,创建参数
		Tiger tiger = new Tiger();
		person.eat(tiger);
		
		Rabbit rabbit = new Rabbit();
		person.eat(rabbit);
		
		//通用的方式的调用,多态:同一个Animal但是最终结果是不同的
		Animal tiger2 = new Tiger();
		person.eat(tiger2);
		
		Animal rabbit2 = new Rabbit();
		person.eat(rabbit2);
		
		Animal cat = new Cat();
		person.eat(cat);
	}
}


小结

1)java面向对象
a. 面向过程:关注代码编写步骤,解决每个步骤中技术难点,使用工具代码实现即可
b. 面向对象:关注实体创建(建模)特征(私有属性)公有的get和set方法,eat()业务方法,然后咱步骤实现
c. 面向切面:AOP 它是面向对象的有益补充,但是必须现有面向对象,才有面向切面
d. 面向服务:SOA,SOA最佳实践:微服务 SpringCloud Alibaba
2)面向对象这种编程思想为何会胜出面向过程?
需求变更(满足一定的代码变化)
取个平衡点,编程要适度(超市不可能把所有的商品建模,可以超出当前的需求,把常用的都建模)
主流的开发思想是使用面向对象,java,c++,python
3)面向对象概念:三大特征
a. 封装:被隐藏起来,开发者需要知道的内容就少了,代码也更加少,好处开发者容易学习
b. 继承:两种实现方式
b1:extends 继承类,公用代码都写在父类中,代码量急剧降低,每个子类无需写相同重复代码,复用
b2:implements 实现接口,没有少写代码,它的作用就是定义规范,所有的子类都必须遵守
c. 多态:同一个事务可以展现出不同的结果 Animal tiger.eat 吃肉肉,rabbit.eat 吃草草
好处,代码通用,向后兼容 Tiger,Rabbit
4)封装具体的实现
a. 创建实体类 entity
b. 一堆的私有属性(特性),外部不能直接访问 private String name;
c. 一堆的get和set方法来调用(行为)getName()、setName();
d. 一堆业务的方法(行为) eat(), play()。。。
5)类的继承
a. java单继承,就想继承多个类?多级继承,爷爷-父亲-我,没有c语言多继承灵活,但安全,不易出错,出错好找的问题的所在类
b. 把公用的代码就写在父类中
c. 怎么表达是当前的类 this,还是父类 super?
d. 子类调用 Fruit 水果是父类,Apple是子类,怎么调用父类方法
d1)声明它们之间的关系,继承关系:class Apple extends Fruit
d2)调用 Apple apple = new Apple(); apple.eat(); 执行时,先到本类查找,没有eat方法,它就去父类查找方法eat()
好处:复用代码 apple可以调用fruit.eat(),pear可以调用fruit.eat()
6)接口的实现
a. 定义接口,只写方法的定义。规定方法返回值,方法名称,方法的参数
b. 实现接口 Animal tiger = new Tiger(); 关系表达 class tiger implements Animal;
c. 在tiger就必须实现Animal接口中所有的方法定义
好处:规范代码,实现向后兼容,程序就方便扩展 JDBC
主流开发方式提倡,面向接口开发!
7)类和接口的本质差异
a. 类使用class修饰,接口使用 interface修饰
b. 类中内容都必须实现,接口中没有实现的代码
c. 类是可以被extends继承的,任何类都可以有子类;接口实现接口(多级)
d. 类干活,接口不干活
8)多态
a. 同一个类,表现出不同的结果

package test;

public class TestMain {
public static void main(String[] args) {
int i = 100; //整数
String s = “abc”; //字符串

	//运行时多态
	System.out.println(i);
	System.out.println(s);
}

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值