封装,继承,多态
Java基础_创建类,对象_局部,成员变量_权限修饰符_方法的重写_构造器_代码块_11
Java四大关键字this,static,final,super_13
封装(Encapsulation)
封装的定义
封装:将某些东西进行隐藏,然后提供相应的方式进行获取。
封装的好处:提高代码的安全性
我们程序设计追求“高内聚,低耦合”。
➢高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
➢低耦合:仅对外暴露少量的方法用于使用。
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提
高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露
的暴露出来。这就是封装性的设计思想。
public class Girl {
public void Girl(){
}
private int age;
//读取年龄的方法
public int getAge(){
return age;
}
//设置年龄
public void setAge(int age){
if(age>=30){
this.age = 18;
}else{
this.age = age;
}
}
}
public class Test {
public static void main(String[] args) {
Girl g = new Girl();
g.setAge(100);
System.out.println(g.getAge());
}
}
上面的代码,对于属性age来说,我加了修饰符private,这样外界对它的访问就受到了限制,现在我还想加上其他的限制条件,但是在属性本身上没有办法再加了,所以我们通过定义方法来进行限制条件的添加。
进行封装的方法
- 私有化,被private修饰–》加入权限修饰符(其他修饰符也行)
一旦加入了权限修饰符,其他人就不可以随意的获取这个属性 - 提供public修饰的方法让别人来访问/使用
- 即使外界可以通过方法来访问属性了,但是也不能随意访问,因为咱们在方法中(set和get)可以加入 限制条件。
提高:
public class Student {
private int age;
private String name;
private String sex;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
if("男".equals(sex)||"女".equals(sex)){
this.sex = sex;
}else{
this.sex = "男";
}
}
//加入构造器
public Student(){
}
public Student(int age,String name,String sex){
this.age = age;
this.name = name;
this.setSex(sex);
}
}
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.setAge(15);
stu.setSex("女");
stu.setName("ZhouT");
System.out.println(stu.getSex()+
stu.getName()+
stu.getAge());
Student stu2 = new Student(18,"ZhouTao","ad");
System.out.println(stu2.getSex()+stu2.getName()+stu2.getAge());
}
}
PS:上面只是对属性进行封装,其实大到框架也能进行封装。使用权限修饰符。
继承(Inheritance)
继承概念的引入
类是对象的抽象:
IPhone X,Lenovo,小米 10,HUAWEI Mate 30——>手机类
继承是对类的抽象:
学生类:
Student: 属性:姓名,年龄,身高,学生编号
方法:吃饭,睡觉,喊叫,学习
·
教师类:
Teacher: 属性:姓名,年龄,身高,教师编号
方法:吃饭,睡觉,喊叫,教学
·
员工类:
Emploee: 属性:姓名,年龄,身高,员工编号
方法:吃饭,睡觉,喊叫,工作·
共同的东西: 人类:
属性:姓名,年龄,身高
方法:吃饭,睡觉,喊叫
·
学生类/教师类/员工类 继承 自 人类
·
·
以后定义代码:
先定义人类:
人类: —》父类,基类,超类
属性:姓名,年龄,身高
方法:吃饭,睡觉,喊叫
·
再定义 : —》子类,派生类
·
学生类:Student:
属性:学生编号
方法:学习
·
教师类:Teacher:
属性:教师编号
方法:教学
·
员工类:Emploee:
属性:员工编号
方法:工作
·子类 继承自 父类
·
继承就是对对各种类相同属性的抽取。
例如:学生是一个人,老师也是一个人,工人也是一个人
就可以把人定义为父类,学生,老师,工人就是他的子类
继承代码的引入
先写父类,再写子类:
父类:人类 Person
子类:学生类 Student
//人类
public class Person {
//属性
private int age;
private String name;
private double height;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
//方法
public void eat(){
System.out.println("吃");
}
public void sleep(){
System.out.println("睡");
}
}
//学生类
public class Student extends Person{
//属性
private int sno;
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
//方法
public void study(){
System.out.println("学习");
}
}
//测试类
public class Demo {
public static void main(String[] args) {
Student s = new Student();
s.setSno(1);
s.setAge(18);
s.setHeight(180.00);
s.setName("Java继承");
System.out.println(s.getSno()+"\t"+s.getName()+"\t"+s.getHeight());
s.eat();
s.study();
s.sleep();
}
}
继承的好处
提高代码的复用性:父类定义的内容,子类可以直接拿过来用就可以了,不用代码上反复重复定义了
同时,父类private修饰的内容,子类实际上能继承,因为封装的特性阻碍了直接调用,但是提供了间接调用的方式,可以间接调用。
继承的总结
-
继承关系 :
父类/基类/超类
子类/派生类
子类继承父类一定在合理的范围进行继承的 子类 extends 父类 -
继承的好处
- 提高了代码的复用性,父类定义的内容,子类可以直接拿过来用就可以了,不用代码上反复重复定义了
- 便于代码的扩展
- 为了以后多态的使用。是多态的前提。
- 父类private修饰的内容,子类也继承过来了。
- 一个父类可以有多个子类。
- 一个子类只能有一个直接父类。但是可以间接的继承自其它类。
- 继承具有传递性:Student -->继承自 Person —>继承自Object
Object类是所有类的根基父类。
所有的类都直接或者间接的继承自Object。
多态(Polymorphism)
多态和属性无关,多态是指对方法的多态,而不是属性的多态。
定义:多态就是多种状态:同一个行为,不同的子类表现出来不同的形态。多态指的就是同一个方法调用,然后由于对象不同会产生不同的行为。
代码引入
父类:小动物
public class Animal {
public void shout(){
System.out.println("我是小动物,我可以叫");
}
}
小猫咪:
public class Cat extends Animal{
public void shout(){
System.out.println("喵喵喵");
}
public void scratch(){
System.out.println("喵喵要挠死你");
}
}
小狗:
public class Dog extends Animal{
public void shout(){
System.out.println("汪汪汪");
}
public void guard(){
System.out.println("汪汪可以看家护院");
}
}
小猪:
public class Pid extends Animal {
public void shout() {
System.out.println("小猪哼哼哼");
}
public void eat(){
System.out.println("猪猪要吃东西");
}
}
小女孩:
public class Girl {
//跟小动物玩
public void play(Animal an){
an.shout();
}
}
测试类:
public class Test {
public static void main(String[] args) {
//具体的猫
//Cat c = new Cat();
//具体的小女孩
Girl g = new Girl();
//小女孩和猫咪玩儿
// g.play(c);
//小女孩和狗狗玩儿\
//Dog d = new Dog();
//g.play(d);
//具体的动物
//Cat c = new Cat();
Dog d = new Dog();
Pid p = new Pid();
Animal an = p;
g.play(an);
}
}
要是没有多态,这个小女孩跟小动物玩耍就需要写很多代码,既要重载一个跟猪玩耍,也要写跟猫咪玩耍,还要跟狗狗玩耍的方法,然而有了多态,只要写一个猪猪,猫咪,狗狗的父类小动物Animal,然后在女孩类写一个跟小动物玩耍的方法。就省去了小女孩小女孩和猪猪,猫咪,狗狗各自的代码。
泛化
先有子类,再抽取父类 为泛化
而先有父类,再有子类:为继承
多态的好处:
为了提高代码的扩展性,符合面向对象的设计原则:开闭原则。
开闭原则:指的就是扩展是开放的,修改是关闭的。
PS:多态可提高扩展性,但没有达到最好。反射的扩展性可以达到最好。
三个要素
- 继承·······Cat extends Animal ,Pig extends Animal, Dog extends Animal
- 重写:子类对父类的方法shout()重写
- 父类引用指向子类对象:
Pig p = new Pig();
Animal an = p;
将上面的代码合为一句话:Animal an = new Pig();
Animal an :编译期的类型
new Pig():运行期的类型
public void play(Animal an){//Animal an = an = new Pig();
an.shout();
}
上面的代码,也是多态的一种非常常见的应用场合:父类当方法的形参,然后传入的是具体的子类的对象,然后调用同一个方法,根据传入的子类的不同展现出来的效果也不同,构成了多态。
内存分析
向上转型,向下转型
Java中的继承机制使得一个类可以继承另一个类,继承的类称为子类,被继承的类称为父类。
在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象,所以子类可以继承父类中所有的属性和方法,包括private修饰的属性和方法,但是子类只是拥有父类private修饰的属性和方法,却不能直接使用它,也就是无法直接访问到它(子类可以通过调用父类的public声明的get方法来获取父类的private属性,但无法访问父类的private方法)。同时子类可以对继承的方法进行重写(@Override),并且新建自己独有的方法。
详情:向上转型和向下转型
public class Demo {
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
Pig p = new Pig();
Animal an = p;//转型:向上转型
an.shout();
//加入转型的代码:
//将Animal转为Pig类型:
Pig pig = (Pig)an ;//转型:向下转型
pig.eat();
pig.age = 10;
pig.weight = 60.8;
}
}
简单工厂设计模式
不仅可以使用父类做方法的形参,还可以使用父类做方法的返回值类型,真实返回的对象可以是该类的任意一个子类对象。
简单工厂模式的实现,它是解决大量对象创建问题的一个解决方案。将创建和使用分开,工厂负责创建,使用者直接调用即可。简单工厂模式的基本要求是
-
定义一个static方法,通过类名直接调用
-
返回值类型是父类类型,返回的可以是其任意子类类型
-
传入一个字符串类型的参数,工厂根据参数创建对应的子类产品
public class Test {
public static void main(String[] args) {
Girl g = new Girl();
//Cat c = new Cat();
//Dog d = new Dog();
//Pig p = new Pig();
Animal an = PetStore.getAnimal("狗");
g.play(an);
}
}
public class PetStore {//宠物店 ---》工厂类
//方法:提供动物
public static Animal getAnimal(String petName){
Animal an = null;
if("猫".equals(petName)){//petName.equals("猫") --》这样写容易发生空指针异常
an = new Cat();
}
if("狗".equals(petName)){
an = new Dog();
}
if("猪".equals(petName)){
an = new Pig();
}
return an;
}
}
有不懂的地方可以私信~
内容来源于马士兵教育赵珊珊老师的Java笔记。