什么是封装
-
封装:就是将类中的属性设为私有化,之前所学的类中多使用public对类中的属性进行定义,pubic是一个公共属性可以被全局调用,而封装使用private对当前类的属性进行私有化,使得程序不能直接通过“ 类名. ”的方式进行调用。
封装大多指针对于类的属性,基本不对类的方法进行封装 -
封装的好处:
1. 使得数据更加安全,提高程序的安全性
2. 使得程序更加规范化,统一接口:想要调用类中的数据或者对类中的数据进行赋值只能通过编写的get,set方法调用。
3. 隐藏代码的细节:使得代码更加简洁,对于用户使用更加便利。
4. 增加了系统的可维护性:维护系统时针对某个数据对其数据相关的类进行维护。
5. 可以判断数据的合法性:在类中对属性的set方法进行数据合法化的规定,以实现数据的合法化 -
封装的实现:
接下来将编写一个学生类,并且将对类中学生的姓名,学号两个属性进行封装,对年龄不进行封装以便于对于封装与不封装之间调用的区别。
package com.oop.Demo02;
//这是一个学生类,并且将对类中学生的姓名,两个属性进行封装,对年龄学号不进行封装以便于对于封装与不封装之间调用的区别。
public class student {
//对类中学生的姓名,学号两个属性进行封装
private String name;
private String xuehao;
/**
* 想要对封装的属性进行调用需要编写对应的get,set方法
* get方法用于获取类中对应属性的值
* set方法用于定义或更改类中属性的值
* @return
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getXuehao() {
return xuehao;
}
public void setXuehao(String xuehao) {
this.xuehao = xuehao;
}
/**
* 不对年龄进行封装,便于对比
* 未封装的属性调用不需要通过get,set方法
*/
public int age;
}
- 封装后属性的调用和修改:
package com.oop;
import com.oop.Demo02.student;
//作为Demo02这个包的主启动类,按照正常情况而言,一个程序只会有一个main方法
public class Application {
public static void main(String[] args) {
//new 实例化对象
student st = new student();
//对封装后的数据进行调用
//修改封装后的数据
st.setName("大美女");
st.setXuehao("3749302");
//对封装的数据进行输出
System.out.println(st.getName());
System.out.println(st.getXuehao());
//对未封装的属性进行修改
st.age=32;
//调用输出未封装的属性的数据
System.out.println(st.age);
}
}
- 方法的重载:就是使用同一个方法名,不同的方法。
继承
什么是继承
-
继承是java中类和类的关系,将其中一个类设为父类,一个类设为子类,子类在继承后可以直接使用父类中的一切公有的属性或者方法。需要注意的是一个父类有可以有多个子类,但是一个子类只能有一个父类。
-
java中的所有类都直接或者间接的继承object类。
-
代码实现
- 父类的实现
package com.oop.Demo03;
//将人这个类作为父类
public class Person {
public void say(){
System.out.println("你好");
}
}
2. 子类的实现
package com.oop.Demo03;
//学生 is 人
//所以学生是人的子类,并且通过extend继承Person这个父类
public class student extends Person{
}
- 子类对父类继承的调用
package com.oop;
import com.oop.Demo03.student;
//作为Demo02这个包的主启动类,按照正常情况而言,一个程序只会有一个main方法
public class Application {
public static void main(String[] args) {
//直接对student类进行实例化,并调用Person类中的say方法
student st = new student();
st.say();
}
}
需要注意的是在student这个类中并没有存在say这个方法,say这个方法存在于Person这个父类中,student子类通过继承后可以对say方法进行调用
ctrl+h 打开关系树状图
super和this的区别
-
对调用范围的不同:
- this调用的事当前类的对应属性,super调用的是当前类的父类的被保护的值。
- 都可以调用构造方法,但是调用的构造方法不同,super()调用当前类的父类的构造方法,this()调用当前类的构造方法。两种方法不能同时使用
- this当前类没有继承任何类也可以使用,super必须在继承类的条件下使用。
-
调用属性范围不同的代码示例:
- 父类代码
package com.oop.Demo03;
//将人这个类作为父类
public class Person {
protected String name="person";
public void print(){
System.out.println("Person");
}
}
子类代码:
package com.oop.Demo03;
//学生 is 人
//所以学生是人的子类,并且通过extend继承Person这个父类
public class student extends Person{
private String name="student";
public void test(String name){
System.out.println(name);//这里的name是main函数所传递的name的值
System.out.println(this.name);//是当前类的name对应的值
System.out.println(super.name);//是当前类的父类中name对应的值
}
}
主函数调用:
import com.oop.Demo03.student;
//作为Demo02这个包的主启动类,按照正常情况而言,一个程序只会有一个main方法
public class Application {
public static void main(String[] args) {
//区分super和this调用的区别
student student = new student();
student.test("123");
}
}
- 调用方法范围不同的代码示例:
父类代码:
package com.oop.Demo03;
//将人这个类作为父类
public class Person {
protected String name="person";
public void print(){
System.out.println("Person");
}
}
子类代码:
public class student extends Person{
private String name="student";
public void print(){
System.out.println("学生");
}
public void test1(){
print();//当前类的方法
this.print();//当前类的方法
super.print();//当前类的父类的方法
}
主启动类代码:
import com.oop.Demo03.student;
//作为Demo02这个包的主启动类,按照正常情况而言,一个程序只会有一个main方法
public class Application {
public static void main(String[] args) {
//区分super和this调用的区别
student student = new student();
student.test("123");
student.test1();
}
}
多态
-
什么是多态: 多态是指同一种方法可以根据应用对象不同的不同实现不同的行为方式。比如有一个父类叫做Person,一个子类叫做student,当父类中含有一个方法叫做say()而子类不含有这个方法时,实例化对象对其的调用实际是调用父类中的方法,当子类对父类的方法进行重写后,对该方法进行调用实际是调用的子类的方法。
-
多态是方法的多态,属性不存在多态
-
多态要求父类和子类存在联系,对父类引用只存在于子类的方法时可以对父类的类型进行强转。
-
多态的存在条件:
1. 要求两个类之间有继承关系
2. 方法需要被重写
3. 父类的引用需要指向子类对象:Person st=new student(); -
哪些方法不可以被重写:
- static 方法:静态方法属于一个类,不属于实例化对象
- final :final修饰的对象位于常量词中,无法被改变
- private:private是一个私有的方法不能对重写或调用
-
多态实例:
-
父类代码:
package com.oop.Demo04;
//该包仅用于对多态的解释
public class Person {
public void say(){
System.out.println("父类");
}
}
- 子类代码(含重写):
package com.oop.Demo04;
public class Student extends Person{
@Override// @Override用于表示以下方法是对父类中方法进行重写,同时可以检查以下方法名是否在父类重0存在
public void say(){
System.out.println("子类");
}
}
- 启动类:
package com.oop;
import com.oop.Demo04.Person;
import com.oop.Demo04.Student;
//作为Demo02这个包的主启动类,按照正常情况而言,一个程序只会有一个main方法
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的,但是引用对象是不确定的
//多态中需要父类的引用指向子类的实际类型
//引用对象 实例化对象名=new 对象实际类型
Student st1 = new Student();
Person st2 = new Student();
//当只有父类存在say();方法时,调用执行的是父类中的方法
//st2.say();
//st1.say();
//当父类中的方法被子类重写后不管是父类的引用还是子类都引用都调用子类
//中的重写方法。
st2.say();
st1.say();
}
}
instanceof的应用
- instanceof用于判断两个类是否存在父子关系,当存在是返回值为TRUE,不存在是返回FALSE。
package com.oop;
import com.oop.Demo04.Person;
import com.oop.Demo04.Student;
//作为Demo02这个包的主启动类,按照正常情况而言,一个程序只会有一个main方法
public class Application {
public static void main(String[] args) {
Student student = new Student();
System.out.println(student instanceof Person);
System.out.println(student instanceof Object);
System.out.println(student instanceof Student);
// teacher和student是同级不存在父子关系,编译时就会报错
// System.out.println(student instanceof teacher);
}
}
子父类间的类型转换
将子类转换为为父类,但是需要注意的是将子类转换为父类时将会丢失一些只存在于子类中的方法
- 子父类间的类型转换可以方便方法的调用,减少代码的重复性。
- 子类转换为父类(不用强制转换)
Student student = new Student();
//将子类转换为为父类,但是需要注意的是将子类转换为父类时将会丢失一些只存在于子类中的方法
Person person=student;
- 父类转换为子类(强制转换)
//高类型的转换为低类型的
//对象类型 对象名=(强转类型)高类型对象名
Student st1=(Student) person;
((Student)person).say();//这是另外一种写法的类型转化
//当父类转化为子类后可以直接调用只存在于子类中的方法