1.封装
目的:保护内部的属性和方法细节,控制获取和修改的权限,保障内部(属性和方法)的安全
1.实现方式
(1)属性私有
使用private修饰的属性,只能在本类的内部访问
/* 封装 private / set、get
*/
package p1;
public class Test10{
public static void main(String[] args){
//创建A类对象a01
A a01= new A();
a01.name="zhangsan";//调用A类私有化属性name error!
a01.age=20; //调用A类私有化属性age error!
}
}
class A{
private String name; //私有化属性name
private int age; //私有化属性age
public A(){
//测试代码块:作用是测试无参的A类构造方法是否运行
System.out.println("我是测试代码块/A类的无参构造方法");
}
public void eat(){
}
}
运行结果:
(2)为每个属性提供公开的set/get方法
//语法:
//get(获取)/获取属性
public 返回值类型 get+属性名(){
return 属性;
}
//set(设置)/设置属性
public void set+属性名(参数数据类型 参数名){
this.属性名=属性名;
}
//(属性名单词第一个字母要大写)
2.访问形式
//封装前
//为属性赋值
sb.password="123456";
//获取属性
sb.password;
//封装后
//为属性赋值
sb.setPassword("123456");
//访问 获取属性
sb.getPassword();
2.继承
1. is a 关系
满足里氏代换原则 lsp:当is a 关系成立时,前者一定具备后者的特征与行为
例如:正例:M4 is a 枪
类与类之间也可以实现is a 关系 即 子类(派生类)是一种父类(超类、基类)
例如:学生 is a 人
正例:students 类就是person父类
所以students类就可以继承父类person
2.语法
//定义类时
class 子类 extends 父类
例如:class Students extends Person{}
注意:1. java中的继承关系为单继承关系,一个类只能有一个父类,可以多级继承(树形继承 例如:家谱)
2.私有属性可以被继承(成为子类的一部分)但是不能被访问。(继承后存于子类 但是子类没权利访问)
3.访问权限修饰符
修饰符 | 本类 | 同包或同包子类 | 其他包的子类 | 任何位置/其他包 |
private | √ | |||
default(默认) | √ | √ | ||
protected(受保护) | √ | √ | √ | |
public | √ | √ | √ | √ |
4.方法的覆盖(override)继承中出现的方法覆盖现象
当父类所定义的方法不再满足子类需求时,可在子类中声明一个与父类相同的方法进行覆盖
//语法要求
//返回值类型 方法名 参数表 与父类方法相同 访问权限相同或更宽
class A{
public int eat(){
System.out.println("A在吃");
return 0;
}
}
class B extends A{
public int eat(){
System.out.println("B覆盖了A的eat()方法");
return 0;
}
}
注意:
①.参数表不同不算覆盖 是方法的重载
②.父类的私有方法对于子类来说是不可见的,不会对父类方法构成覆盖
5.super关键字
在子类中 表示父类对象
作用:
(1)可以在子类中通过super.访问父类的属性或方法(一般用于被覆盖后的方法)
(2)多级继承时,创建子类对象先找到顶级父类,再由从父到子的顺序依次创建对象
注意:1.可以在子类的构造方法中使用super()、super(实参)通知虚拟机
2.super()只能出现在构造方法的第一行
3.如果构造方法的第一行没有this()或this(实参)则隐式包含super()
6.创建对象的过程
①分配内存空间(父类、子类)
②初始化父类属性
③调用父类构造方法
④初始化子类属性
⑤调用子类的构造方法 (多级继承时,创建子类对象先找到顶级父类,再由从父到子的顺序依次创建对象)
3.多态
1.概念
父类引用指向不同的子类对象,从而产生多种形态
//代码演示多态
public class Test01{
public static void main(String[] args){
Person p01;
p01=new Students();
p01=new Worker();
//总结 一个person类的引用数据类型 p01 但是可以变成子类students类的对象 也可以是子类Worker类的对象
}
}
//父类Person
class Person{
}
//子类students类继承person类
class Students extends Person{
}
//子类Worker类继承Person类
class Worker extends Person{
}
2.特点
(1)子类对象类型始终不变
(2)编译时,只能是调用父类引用类型中的声明的方法
(3)运行时,如果子类覆盖了父类的方法,则调用子类覆盖的方法
小秘诀:如果要看属性 看等号“=”左边 左边是谁就是谁的
如果看方法 看等号“=”右边 右边是谁就用谁的
3.类型转换
(1)子类对象赋值父类引用
Person p01=new Students();
(2)父类引用赋值给子类引用
①当需要使用子类中的独有的方法 此时需要向下转型
Person p01=new Students();
②编译器认为p01引用中存在的对象是多种的 不一定能转换成功
可能编译出错 需要强制类型转换
//强制类型转换
//创建父类Person引用的子类对象
Person p01=new Students();
//强制转化成Students子类对象
Students s01=(Students)p01;
//强制转化语法
子类类名 对象名= (子类数据类型)父类数据的子类对象
注意:运行时易出现:java.classCastException错误
4.instanceof关键字
作用:判断引用类型中存放对象,是否为指定类型
语法:引用 instanceof 类名
//语法要求
//一般:
Boolean a= p01 instanceof Students;
结果为true则是这个类型 false相反
5.多态的作用
(1)屏蔽子类的差异
例如:一个父类的引用对象可以创建多个子类对象 然后调用各个不同子类的独特重写方法 返回值皆为父类即可
(2)利于拓展 降低程序的耦合度