【JAVA】06 封装、继承、多态 总结(初级)
教程:B站韩顺平
目录
- 一、访问修饰符
- 二、封装
- 三、继承
- 3.1 继承
- 3.1.1 super关键字
- 3.2 继承
- 3.2.1 概念
- 3.2.2 继承的本质
- 3.2.3 方法重写/覆盖
- 3.2.3.1 方法重载和方法重写的比较
- 四、多态
- 4.1 方法的多态
- 4.2 对象的多态
- 4.3 向上转型
- 4.4 向下转型
- 4.5 多态——属性
- 4.6 多态——instanceOf
- 4.7 动态绑定机制❤️
- 4.8 应用
- 4.8.1 多态数组
- 4.8.2 例题
- 五、Object类
- 5.1 == 和 equal
- 5.2 HashCode
- 5.3 toString()
- 5.4 finalize
一、访问修饰符
二、封装
- 将属性进行私有化【不能直接修改属性】
- 提供一个公共的set方法,用于对属性判断并赋值
- 提供一个公共的fet方法,用于获取属性的值
tips:将有防护功能的方法写在构造器中,也可以实现防护属性
三、继承
3.1 继承
继承可以解决代码复用,当多个类存在相同属性(变量)和方法时,可以从种抽取父类,在父类中重新定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends继承即可
3.1.1 super关键字
super表示父类的引用,用于访问父类的属性,方法,构造器
基本语法
- 访问父类的属性,不能访问父类的private属性
super.属性名
- 访问父类的方法,不能访问父类的private方法
super.方法名(参数列表);
- 访问父类的属性,不能访问父类的private属性
访问父类的构造器:super(参数列表只能放在构造器的第一句,只能出现一句!)
student.javapublic class student {private String name;private int age;public student(){}public student(String name, int age){setName(name);setAge(age);}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public int getAge() {return age;}}
pupil.java
public class pupil extends student{private double grades;public pupil(){}public pupil(String name, int age,double grades){super(name,age);setGrades(grades);}public void setGrades(double grades) {this.grades = grades;}public double getGrades() {return grades;}}
testing.java
public class testing {public static void main(String[] args) {pupil p = new pupil("小明",18,100.00);System.out.printf("name:%s,\tage:%d,\tgrades:%.2f",p.getName(),p.getAge(),p.getGrades());}}
调用方法的顺序:
先找本类,如果有,则调用
如果没有,则找父类,并可以调用,则调用
如果父类没有,则继续找父类的父类,整个规则相同,直到Object类
tips:
a. 如果查找方法的过程中,找到了,但是不能访问,则报错
b. 如果查找方法的过程中,没有找到,则提示方法不存在
c. super.cal()是直接查找父类,其他规则一样(从b步骤开始)
d. 当子类中有和父类中的成员(属性和方法)重名是,为了访问父类的成员,必须通过super,如果没有重名,使用super、this、直接访问时一样的效果
e. super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super取访问爷爷类的成员,如果多个基类含有相同的属性名,则使用super访问遵循就近原则,A——>B——>C,同时也需要遵守访问权限的相关规则super和this的比较
3.2 继承
3.2.1 概念
- 子类继承了所有类的属性和方法,非私有属性和方法可以在子类中直接访问,但是私有属性不能再子类直接访问,要通过公共的方法访问
- 子类必须调用父类的构造器,完成父类的初始化
- 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会调用父类的无参构造器
- 如果父类没有提供无参构造器,则必须在子类的构造器中使用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则编译不通过
- 如果希望指定去调用父类的某个构造器,则显式的调用一下
- super在使用时,需要放在构造器第一行
- super和this都只能放在构造器第一行,因为这两个方法不能共存在同一个构造器中
- java所有类都是Object类的子类,Object是所有类的基类
- 父类构造器的调用不限于直接父类,将一直往上追溯直到Object类(顶级父类)
- 子类最多只能继承一个父类(指直接继承),即java中是单继承方式
- 不能滥用继承,子类和父类之间必须满足is-a的逻辑关系
3.2.2 继承的本质
当子类对象创建好后,建立查找的关系
public class ExtendsTheory{public static void main(Strings[] agrs]){Son son = new Son(); }
}
class GrandPa{String name = "爷爷";String hobby = "旅游";
}
class Father extends GrandPa{String name = "爸爸";int age = 39;
}
class Son extends Father{String name = "儿子";
}
- 由于只创建一个Son对象,故堆中只划分了一块区域
- 然后再在方法区创建按照 Object——>Son的顺序创建对象
- 调用方法时按照 本类——>Object的顺序进行查找(继承的顺序)
3.2.3 方法重写/覆盖
- 子类方法的形参列表,方法名要和父类的一样
- 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类
eg:父类:返回类型Object
子类:返回类型String - 子类方法不能缩小父类方法的访问权限:public>protected>默认>private
3.2.3.1 方法重载和方法重写的比较
四、多态
4.1 方法的多态
重写+重载
4.2 对象的多态
一个对象的编译类型和运行类型可以不一致
编译类型在定义对象时就确定了,不能改变
运行类型是可以变化的
编译时类型由声明该变量时使用的类型决定,编译时引用变量只能调用其编译类型所具有的方法。
运行时类型由实际赋给该变量的对象决定。
编译类型看定义时=的左边,运行类型看=的右边
//Animal.java public class Animal {private String name;public Animal(){}public void cry(){System.out.println("cyr:animal");} } //Dog.java public class Dog extends Animal{public void cry() {System.out.println("cry dog");} } //Cat.java public class Cat extends Animal{public void cry(){System.out.println("cry: cat");} } //PolyObject.java public class PolyObject {public static void main(String[] args){Animal animal = new Dog(); //编译类型:Animal,运行类型Doganimal.cry();animal = new Cat();//编译类型:Animal,运行类型catanimal.cry();} }
运行结果:
案例
//Animal.java public class Animal {private String name;public Animal(String name){this.name=name;}public String getName(){return this.name;} } //Dog.java public class Dog extends Animal{public Dog(String name){super(name);}public void cry() {System.out.println("cry dog:"+this.getName());} } //Food.java public class Food {private String name;public Food(String name){this.name=name;}public String getName(){return this.name;} } //Rice.java public class Rice extends Food{public Rice(String name){super(name);} } //PolyObject.java public class PolyObject {public static void main(String[] args){Animal animal = new Dog("大黄");animal.cry();Food food = new Rice("黑米粥");Master master = new Master("杰西");master.feed(animal,food);} }
4.3 向上转型
前提:两个对象(类)存在继承关系
本质:父类的引用指向了子类的对象
语法:父类类型
引用名=new 子类类型() Animal animal = new Dog();
特点:编译类型看左边,运行类型看右边
可以调用父类中的所有成员(需要遵循访问权限)
不能调用子类中特有成员
最终运行效果看子类的具体实现(即运行时,按照运行类型决定)
4.4 向下转型
语法:子类类型
引用名 = (子类类型)父类引用; Cat cat = (Cat) animal; //但是要父类的引用必须是指向当前目标类型的引用
只能强转父类的引用,不能强转父类的对象
要求父类的引用必须指向的是当前目标类型的对象
可以调用子类类型中的所有成员
4.5 多态——属性
属性没有重写之说,属性的值看编译类型
4.6 多态——instanceOf
instanceOf比较操作符,用于判断对象的运行类型 是否为xx类型 或者 xx类型的子类型
4.7 动态绑定机制❤️
- 当调用对象方法时,该方法会和该对象的 内存地址/运行类型 绑定
- 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
4.8 应用
4.8.1 多态数组
例1:
public class PolyArray {public static void main(String[] args){Person[] persons = new Person[5];persons[0] = new Student("小明",100);persons[1] = new Student("大明",400);persons[2] = new Teacher("大强",20000);persons[3] = new Teacher("小强",50000);persons[4] = new Teacher("中强",90000);for(int i=0;i<persons.length;i++){persons[i].say();if(persons[i] instanceof Student){((Student) persons[i]).study();}else if(persons[i] instanceof Teacher){((Teacher) persons[i]).teach();}else{System.out.println("类型错误");}}}
}
class Person {private String name;public Person(String name){this.name=name;}public String getName() {return this.name;}public void say(){System.out.println(this.name);}
}
class Student extends Person{private double grades;public Student(String name,double grades){super(name);this.grades = grades;}public double getGrades() {return grades;}public void say(){System.out.println("学生"+this.getName()+"成绩"+this.getGrades());}public void study(){System.out.println("学生"+this.getName()+"正在学习");}
}
class Teacher extends Person{private double salary;public Teacher(String name,double salary){super(name);this.salary = salary;}public double getSalary() {return salary;}public void say(){System.out.println("教师"+this.getName()+"薪酬"+this.getSalary());}public void teach(){System.out.println("教师"+this.getName()+"正在教书");}
}
4.8.2 例题
//Employee.java
public class Employee {private String name;private double salary;public Employee(String name, double salary){this.name=name;this.salary=salary;}public String getName() {return name;}public double getSalary() {return salary;}public double getAnnual(){return this.salary*12;}
}//CommenEmployee.java
public class CommenEmployee extends Employee{public CommenEmployee(String name, double salary){super(name,salary);}public void work(){System.out.println("普通员工:"+super.getName()+"正在工作");}
}//Manager.java
public class Manager extends Employee{private double bonus;public Manager(String name,double salary,double bonus){super(name,salary);this.bonus = bonus;}public double getBonus() {return bonus;}public void manage(){System.out.println("经理:"+super.getName()+"正在管理");}
}//PolyParametersTesting.java
public class PolyParameterTesting {public void showEmpAnnual(Employee e){double salary = e.getSalary();if(e instanceof Manager){salary+=((Manager) e).getBonus();}System.out.println(salary);}public void testWork(Employee e){if(e instanceof CommenEmployee){((CommenEmployee)e).work();}else if(e instanceof Manager){((Manager)e).manage();}else {System.out.println("类型出错");}}
}//PolyParameters.java
public class PolyParameter {public static void main(String[] args){Employee[] es = new Employee[2];es[0] = new CommenEmployee("员工",1000);es[1] = new Manager("经理",2000,500);PolyParameterTesting ppt = new PolyParameterTesting();for(int i=0;i<es.length;i++){ppt.showEmpAnnual(es[i]);ppt.testWork(es[i]);}}
}
五、Object类
5.1 == 和 equal
- ==:
- 既可以判断基本类型,又可以判断引用类型
- 如果判断基本类型,判断的是值是否相等
- 如果判断引用类型,判断的是地址是否相等,即判断是否是同一个对象
- equals:
是Object类中的方法,只能判断引用类型
默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等
public boolean equals(Object obj){return (this ==obj); }public boolean equals(Object obj){if(obj instanceOf Integer){return value=((Integer)obj).intValue(); }return false; }
5.2 HashCode
- HashCode返回该对象的哈希码值,支持此方法是为了提高哈希表的性能
- 提高具有哈希结构的容器的效率
- 两个引用,如果指的是同一个对象,则哈希值肯定是一样的
- 两个引用,如果指向的不同对象,则哈希值是不一样的(但是也有可能一样:哈希碰撞)
- 哈希值主要是根据地址号来的!不能完全将哈希值等价于地址
- 在集合中,HashCode如果需要的话,也会重写
5.3 toString()
默认返回:全类名+@+哈希值的十六进制【查看Object的toString方法】
子类往往重写toString 方法,用于返回对象的属性信息
public String toString(){return getClass().getName()+'@'+Integer.toHexString(hashCode()); }
重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式
public class Employee {private String name;private double salary;public Employee(String name, double salary){this.name=name;this.salary=salary;}public String toString(){return "Employee{" +"name='"+name+'\'' +"salary="+salary+'\''+'}';} }
当直接输出一个对象时,toString方法会被默认的调用
5.4 finalize
- 当对象被回收是,系统自动调用该对象的finalize方法。子类可以重写该方法,做一些释放资源的操作:例如断开数据库链接,关闭文件等
- 如果程序员补充些finalize,则调用Object类的finalize,默认处理
- 如果重写finalze,则可以实现自己的逻辑
- 一般开发的时候不会重写finalize
- 什么时候被回收:当某个对象没有任何引用时,则jvm就认为这个对象是一个垃圾对象,就会使6用垃圾回收机制来销毁该对象,在销毁该对象前,会调用finalize方法
- 垃圾回收机制的调用,是由系统决定的,也可以使用System.gc()主动触发垃圾回收机制
【JAVA】06 封装、继承、多态 总结(初级)相关推荐
- Java的封装继承多态简介与实例
封装 所谓封装就是访问权限控制,不允许调用者直接访问类的属性,使用private修饰,将属性藏起来 此时若创建对象,直接修改属性值,则会报错 想要对属性进行读写则需要在类中添加get/set方法 此时 ...
- (十)Core Java 面向对象(封装,继承,多态,接口) -02 (96)
目录 : 24 ). 面向对象(聚集关系) 25 ). 面向对象(子父类中变量的特点) 26 ). 面向对象(子父类中函数的特点-覆盖) 27 ). 面向对象(子父类中构造函数的特点 ...
- c语言编程 菲薄拉,C语言设计模式-封装-继承-多态
快过年了,手头的工作慢慢也就少了,所以,研究技术的时间就多了很多时间,前些天在CSDN一博客看到有大牛在讨论C的设计模式,正好看到了,我也有兴趣转发,修改,研究一下. 记得读大学的时候,老师就告诉我们 ...
- Java继承_Hachi君浅聊Java三大特性之 封装 继承 多态
Hello,大家好~我是你们的Hachi君,一个来自某学院的资深java小白.最近利用暑假的时间,修得满腔java语言学习心得.今天小宇宙终于要爆发了,决定在知乎上来一场根本停不下来的Hachi君个人 ...
- 大数据笔记8—java基础篇4(面向对象-封装-继承-多态)
面向对象 一.面向对象 1.面向过程 1.2.举例 1.3.总结 二.面向对象 1.简述 2.举例 3.思想特点 2.1.类的定义格式 2.1.1.简述 2.2.2.格式 2.3.3.示例 三.类的使 ...
- Day55-每日一道Java面试题-Java 面向对象编程三大特性: 封装 继承 多态
Java 面向对象编程三大特性: 封装 继承 多态 封装 封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问.但是如果一个类没有 ...
- 小白理解——封装继承多态
一.封装 是什么:首先是抽象,把事物抽象成一个类,其次才是封装.对外表示为一个对象,隐藏对象的属性和动作实现的细节,仅对外公开接口. ...
- 白话文带你了解 封装 继承 多态
这里讲的仅仅是带你理解 封装 继承 多态 染好您可以移步去别的文章学习具体的实现 (只是个人理解 您可以不爱,请别伤害哦!) 首先你要知道 java是面向对象的,说白了就是我拿你当个人,请认清你的地位 ...
- python多态的三种表现形式_python小结----面向对象的三大特征(封装,继承,多态)
面向对象的三大特征: 封装,继承,多态 面向对象的编程思想核心:高类聚,低耦合–程序的设计模式范畴 封装 什么是封装: 在面向对象编程的思想中,对代码进行高度封装,封装又叫包装 封装就是指将数据或者函 ...
- python 参数类型的多态_【Python】面向对象:类与对象\封装\继承\多态
六.Python面向对象--类与对象\封装\继承\多态 1.什么是面向对象编程 1.1 程序设计的范式:程序可控,易于理解 1.2 抽象并建立对象模型 1.3 程序是不同对象相互调用的逻辑.每个对象在 ...
最新文章
- 随想_8_Windows_XP_Explorer_错误
- 2020 年度最佳的23个机器学习项目!(附源代码)
- linux回调函数的使用
- Makefile中关于shell 语句使用的注意事项
- 模拟电路技术之基础知识(七)
- docker desktop 镜像_Spring Boot实战工具4 - Docker
- js 异步操作打开新页面被浏览器拦截的问题
- [Android Pro] 完美解决隐藏Listview和RecyclerView去掉滚动条和滑动到边界阴影的方案...
- SAP MM 采购订单收货被取消了还是不能增加新的delivery cost!
- android 代码写命令,monkey基本命令及脚本编写(示例代码)
- 电机学重读(一)基础知识
- 7分钟学会匿名管道pipe()的使用(内附完整代码测试)
- 【02】 PC端网页布局之CSS3-pink老师-2022/03
- RadarNet: Efficient Gesture Recognition Technique Utilizing a Miniaturized Radar Sensor
- Python3学习笔记(1): print函数用法总结
- 网络安全等级保护细则
- forge不能用java打开_我玩我的世界把java更新了以后,就再也进不了加了forge的版本了,启动器,游戏,forge都重...
- Rockchip平台TP驱动详解
- 目前住院病人主要由护士护理,这样做不仅需要大量护士
- 告别传统机房:3D 机房数据可视化实现智能化与VR技术的新碰撞
热门文章
- SELECT...INTO语法
- 口袋网咖已有服务器在使用怎么注销,口袋网咖怎么登录_口袋网咖登录方法介绍_游戏吧...
- 远程桌面连接和防火墙设置
- 走近“so,neither”开头的倒装句
- 伯明翰高级计算机科学,2020年伯明翰大学高级计算机科学专业本科申请条件及世界排名|学费介绍...
- 大学四年,因为看了这些书,我大二就拿了华为Offer
- ssm毕设项目贵工程线上拍卖平台的设计与实现c1jil(java+VUE+Mybatis+Maven+Mysql+sprnig)
- 带孩子们做环球旅行的读后感_郭晶晶带孩子做家务:做家务的孩子,究竟赢在哪里了?...
- 【Python】红旗超市线下缴电费用户数据分析及可视化(pandas+pyecharts)
- 速卖通关键词挖掘工具_速卖通长尾词采集新增断续功能免费体验7天