简介
Java语言是面向对象编程语言(Object Oriented Programming,OOP),OOP=对象+类+继承+多态+消息,其中核心概念是类和对象。今天我们就来深入的了解一下面向对象的三大特性:封装、继承、多态。
封装
1、什么是封装?
就是用类设计对象处理某一个事物的数据时,应该把要处理的数据,以及处理这些数据的方法,设计到一个类中去。面向对象的三大特征之一:封装。
2、封装的设计规范是什么样的?
合理隐藏,合理暴露。
封装的理念:高内聚、低耦合
这些文字理解能力有限的小伙伴可能会说,也看不懂呀,没关系我们用大白话来翻译一下
什么是封装?
举个栗子:猫:猫有品种、价格、性别、颜色等等属性,可以有抓老鼠、睡觉、晒太阳等等行为活动。
我们要把一只猫用代码设计封装成一个类怎么表示?就是把上面我们想出来的属性和行为封装到一个类里面,
因为每只猫属性是可以变的, 所以属性对应类的成员变量。
而猫的生活行为都差不多,我们假设它都一样,则可以封装成类的成员方法。
具体代码:
public class Cat {
//猫:猫有品种、价格、性别、颜色等等属性,可以有抓老鼠、吃东西、晒太阳等等行为活动。
//封装属性
String breed;//品种
int price;//价格
String sex;//性别
String color;//颜色
//封装行为
//吃东西
public void eat() {
System.out.println(breed+"在吃饭");
}
//工作
public void catchMouse() {
System.out.println(breed+"抓老鼠");
}
}
class Test01{
public static void main(String[] args) {
//创建cat对象并给属性赋值,最后调用方法
Cat cat = new Cat();
cat.breed="橘猫";
cat.color="花色";
cat.price=100;
cat.sex="阉割的公猫";
cat.eat();
cat.catchMouse();
}
}
这就是最简单的封装成一个类,并创建对象,给对象的属性赋值,调用方法。不推荐使用。
这是表面的封装,我们可以深入的封装一下,比如我们可以把属性封装成私有,不让外部直接调用赋值,提供一个赋值窗口给外部,提供一个获取属性值的方法给外部。升级代码如下:
public class Cat {
//猫:猫有品种、价格、性别、颜色等等属性,可以有抓老鼠、吃东西、晒太阳等等行为活动。
//封装属性
private String breed;//品种
private int price;//价格
private String sex;//性别
private String color;//颜色
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
//封装行为
//吃东西
public void eat() {
System.out.println(breed+"在吃饭");
}
//工作
public void catchMouse() {
System.out.println(breed+"抓老鼠");
}
}
class Test01{
public static void main(String[] args) {
//创建cat对象并给属性赋值,最后调用方法
Cat cat = new Cat();
/*
cat.breed="橘猫";
cat.color="花色";
cat.price=100;
cat.sex="阉割的公猫";
*/
cat.setPrice(100);
cat.setColor("花色");
cat.setBreed("橘猫");
cat.setSex("阉割的公猫");
System.out.println(cat.getSex());
System.out.println(cat.getColor());
System.out.println(cat.getBreed());
System.out.println(cat.getPrice());
cat.eat();
cat.catchMouse();
}
}
上面的这个Cat类还差构造器就是标准的java实体类了,属性私有化,提供get/set方法给外界调用属性。来我们给他加上:
package com.it.study;
public class Cat {
//猫:猫有品种、价格、性别、颜色等等属性,可以有抓老鼠、吃东西、晒太阳等等行为活动。
//封装属性
private String breed;//品种
private int price;//价格
private String sex;//性别
private String color;//颜色
//无参构造器
public Cat() {
}
//满参构造器
public Cat(String breed, int price, String sex, String color) {
this.breed = breed;
this.price = price;
this.sex = sex;
this.color = color;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
//封装行为
//吃东西
public void eat() {
System.out.println(breed+"在吃饭");
}
//工作
public void catchMouse() {
System.out.println(breed+"抓老鼠");
}
}
class Test01{
public static void main(String[] args) {
//创建cat对象并给属性赋值,最后调用方法
Cat cat = new Cat();
/*
cat.breed="橘猫";
cat.color="花色";
cat.price=100;
cat.sex="阉割的公猫";
*/
cat.setPrice(100);
cat.setColor("花色");
cat.setBreed("橘猫");
cat.setSex("阉割的公猫");
System.out.println(cat.getSex());
System.out.println(cat.getColor());
System.out.println(cat.getBreed());
System.out.println(cat.getPrice());
cat.eat();
cat.catchMouse();
}
}
在类中封装的设计规范是什么?
在设计类的时候,会将成员变量隐藏,然后成员方法,构造器对外暴露;
隐藏成员变量需要使用到一个修饰符private,被private修饰的成员变量,只能在本类中被访问;
隐藏成员变量: private 数据类型 变量名;
如果被private修饰的成员变量想要在其他类中访问,就必须在成员变量所在的类中提供公共的set\get方法
继承
1.继承是什么?为什么要在程序中使用继承?
继承就是Java中extends关键字。用这个关键字能够使一个类和另一个类建立父子关系。
使用继承能够提高代码的复用率,简化代码,
2、带继承关系的类,Java会怎么创建它的对象? 对象创建出来后,可以直接访问哪些成员?
带继承关系的类,java会用类和其父类,这多张设计图来一起创建类的对象。对象能直接访问什么成员,是由子父类这多张设计图共同决定的,这多张设计图对外暴露了什么成员,对象就可以访问什么成员。
3.方法重写
子类重写父类的方法,可以用自身行为替换父类行为。重写是实现多态的必要备件。
方法重写需要符合下面的三个要点:
1.”= =”: 方法名、形参列表相同。
2重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。声明异常类型相同或更,
3.子类小于等于父类访问权限,子类大于等于父类.
代码演示:
package com.it.study;
//继承
public class ExtendsDome {
public static void main(String[] args) {
//创建对象赋值并调用方法
Dog dog = new Dog();
dog.setName("旺财");
dog.setColor("黑");
dog.setPrice(100);
dog.eat();
dog.lookHome();
System.out.println("-----------");
Cat cat = new Cat();
cat.setName("波斯猫");
cat.setColor("灰色");
cat.setPrice(100);
cat.eat();
cat.catchMouse();
}
}
class Animal{
private String name;//名称
private String color;//颜色
private int price;//价格
public Animal() {
}
public Animal(String name, String color, int price) {
this.name = name;
this.color = color;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
//吃东西
public void eat(){
System.out.println("吃东西");
}
}
class Cat extends Animal{
public Cat() {
}
@Override
public void eat() {
System.out.println(super.getName()+"在吃饭");
}
//工作
public void catchMouse() {
System.out.println(super.getName()+"猫抓老鼠");
}
}
class Dog extends Animal{
public Dog() {
}
@Override
public void eat() {
System.out.println(super.getName()+"在吃饭");
}
//工作
public void lookHome() {
System.out.println(super.getName()+"狗看家");
}
}
上面就是继承的代码演示,里面包含了方法重写,和子类封装自己的特有功能。
多态的简单学习
为什么到了多态就不深入呢?多态比较复杂。
什么是多态?
多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态。
多态的具体代码体现 多态的前提 有继承/实现关系;
存在父类引用子类对象;
存在方法重写。
多态的一个注意事项
多态是对象、行为的多态,Java中的属性(成员变量)不谈多态。
想学深入了解的在我的资源里有一份免费的我学习的笔记,思维导图类的,可以下载。
讲到多态就必须说说抽象类和接口
抽象类就是java中用abstract修饰的类。子类用extends实现父类(这里不细讲)
例如:public abstract class A{public abstract void b();}
接口就是java中用interface关键字实现的一种结构,实现类用implements实现接口(不细讲)
例如:public interface B{ int c();}
例如:
public class C extends A implements B{
public void b(){
System.out.println("这里是抽象类的方法");
}
int c(){
System.out.println("这里是接口的方法");
return 1;
}
}
下面我们就用继承的方式来学习一下多态
package com.it.study;
import java.util.LinkedList;
import java.util.List;
//多态
public class ExtendsDome {
public static void main(String[] args) {
//创建对象赋值并调用方法
//父类引用指向子类对象,有继承。
Animal dog = new Dog();
dog.setName("旺财");
dog.setColor("黑");
dog.setPrice(100);
dog.eat();
//判断dog是否是Dog类型
if (dog instanceof Dog){
((Dog)dog).lookHome();
}
List strings = new LinkedList<>();
System.out.println("-----------");
Animal cat = new Cat();
cat.setName("波斯猫");
cat.setColor("灰色");
cat.setPrice(100);
cat.eat();
//判断cat是否是Cat类型
if (cat instanceof Cat){
((Cat)cat).catchMouse();
}
}
}
abstract class Animal{
private String name;//名称
private String color;//颜色
private int price;//价格
public Animal() {
}
public Animal(String name, String color, int price) {
this.name = name;
this.color = color;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
//吃东西(抽象方法)
public abstract void eat();
}
class Cat extends Animal{
public Cat() {
}
@Override
public void eat() {
System.out.println(super.getName()+"在吃饭");
}
//工作
public void catchMouse() {
System.out.println(super.getName()+"猫抓老鼠");
}
}
class Dog extends Animal{
public Dog() {
}
@Override
public void eat() {
System.out.println(super.getName()+"在吃饭");
}
//工作
public void lookHome() {
System.out.println(super.getName()+"狗看家");
}
}
看代码,我们可以看出这里有一个抽象类Animal,有一个抽象方法eat();创建的对象的类型是Animal,eat()方法在子类不同对象哪里输出的内容不同,这就是多态。