Java基础----封装、继承、多态
文章目录
封装
类变量、成员变量、局部变量
类变量(静态变量):
用static修饰的变量称为静态变量,其内容被该类的所有对象共享,所有对象中这个类变量的值都指向相同的一处内存,随便一个对象修改了此处内存的值都会影响其他对象。
成员变量:
在类中声明的变量,随着对象的建立而建立,存在于对象所在的堆内存中。
局部变量:
在方法中定义的变量,只定义在局部范围内,存在于栈内存中,作用的范围结束,栈帧释放,变量消失。
成员变量以及方法的作用域
在方法定义时,都会加上作用域修饰符(private、default、protected、public),默认情况下为default,不同修饰符作用下,成员变量或方法的作用域是不同的,访问权限如下表所示:
权限修饰符 | 本类 | 同一包下 | 子类同一包下 | 子类不同包下 | 不同包非子类 |
---|---|---|---|---|---|
private | √ | × | × | × | × |
default | √ | √ | √ | × | × |
protected | √ | √ | √ | √ | × |
public | √ | √ | √ | √ | √ |
封装性总结
封装主要是将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏属性的访问和操作,常见的实现方式就是:getter()、setter()。
继承
继承的定义
继承是一种java的机制,子类可以继承父类的所有属性和方法;当子类继承父类时。可以重复使用父类中的属性和方法(覆写),也可以添加新的属性和方法。
继承的实现方式
使用extends关键字用于继承,中文意思延伸,class A extends B,表示A 是B的延伸 ,含义是添加新的功能,在java中被继承的类称为父类,A称为子类
继承的优点
可以重用代码,提高代码的重用性;子类可以通过间接的方式调用父类中的私有属性和私有方法。
多态的描述形式
程序中面向对象的多态性有两种描述形式:
· 方法的多态性:
方法重载(OverLoad):方法名称的重复使用,依据参数类型以及个数区分不同的操作;
方法覆写(OverRide):覆写主要发生在继承结构中,不同的子类依据自身的需要进行父类方法的重新定义。
· 对象的多态性:子类对象在实例化的时候或默认实例化父类对象,所以牵扯到父子对象的转型问题
向上转型:父类 父类对象 = 子类实例;(自动完成)
向下转型:子类 子类对象 = 子类实例,(强制完成)
方法重载
代码如下(示例):
//方法重载
class ball{
public void buy(String str){
System.out.println("买"+str);
}
public void buy(String str,int pr){
System.out.println("买"+ str +"价格" + pr);
}
}
public class Test01{
public static void main(String[] args) {
ball b = new ball();
b.buy("篮球01");
b.buy("篮球02",26);
}
}
方法重载的意义在于同一个方法名称可以完成不同的功能。
方法覆写
代码如下(示例):
//方法覆写
class Ball{
public void play(){
System.out.println("打球");
}
}
class Basketball extends Ball {
public void play() {
System.out.println("打篮球");
}
}
public class Test01{
public static void main(String[] args) {
Basketball ball = new Basketball();
ball.play();
}
}
覆写的核心意义在于,对每一个子类中继承的父类操作可以进一步的实现功能加强,而且可以根据父类中已经存在的标准继续使用。
覆写与重载的区别:
方法重载发生在一个类中,方法名称相同,参数类型及个数不同,方法的返回值类型可以不同,不受限制。
方法覆写发生在继承关系中,方法名称、参数类型以及参数个数完全相同,但被覆写的方法不能有比父类更严格的访问控制权限。
对象向上转型
代码如下(示例):
class Ball{
public void play(){
System.out.println("打球");
}
}
class Basketball extends Ball {
public void play() {
System.out.println("打篮球");
}
}
public class Test01{
public static void main(String[] args) {
Ball ball = new Basketball();
ball.play();
}
}
执行结果为:D:\java\jdk-11\bin\java.exe "-javaagent:D:\IDEA\IntelliJ IDEA 2018.3.2\lib\idea_rt.jar=49275:D:\IDEA\IntelliJ IDEA 2018.3.2\bin" -Dfile.encoding=UTF-8 -classpath D:\JavaTest\out\production\Test01 zhang.da.pao.Test01
打篮球
Process finished with exit code 0
向上转型后发现,调用的是被子类覆写过的方法,虽然接收的类型是父类,但也不会找父类中的相关操作。对象的向上转型的核心在于,要实现所有子类类型的参数操作的统一。
对象向下转型
代码如下(示例):
//向下转型
class Ball{
public void play(){
System.out.println("打球");
}
}
class Basketball extends Ball {
public void play() {
System.out.println("打篮球");
}
//子类中的特有方法
public void special(){
System.out.println("特殊方法");
}
}
public class Test01{
public static void main(String[] args) {
Ball ball = new Basketball();
Basketball b = (Basketball)ball;
b.play();
b.special();
}
}
运行结果:D:\java\jdk-11\bin\java.exe "-javaagent:D:\IDEA\IntelliJ IDEA 2018.3.2\lib\idea_rt.jar=52208:D:\IDEA\IntelliJ IDEA 2018.3.2\bin" -Dfile.encoding=UTF-8 -classpath D:\JavaTest\out\production\Test01 zhang.da.pao.Test01
打篮球
特殊方法
Process finished with exit code 0
子类实例赋值给了父类引用(即完成了向上转型),虽然可以统一处理,但会丢失子类扩展的方法。 所以需要调用子类中的扩展方法时,使用向下转型的特性,重新获得丢失的方法,即强转回子类 。
instanceof 关键字
上文详细介绍了向上转型和向下转型,向上转型只要存在继承关系就可以方便的实现,但向下转型在未发生向上转型时会产生“ClassCastException”异常,使用instanceof关键字可以在转型前判断当前实例是否为某个类的对象。
代码如下(示例):
//instanceof关键字
class Ball{
public void play(){
System.out.println("打球");
}
}
class Basketball extends Ball {
public void play() {
System.out.println("打篮球");
}
//子类中的特有方法
public void special(){
System.out.println("特殊方法");
}
}
public class Test01{
public static void main(String[] args) {
Ball ball = new Basketball();
if(ball instanceof Basketball){
Basketball b = (Basketball)ball;
b.special();
}
}
}
运行结果:D:\java\jdk-11\bin\java.exe "-javaagent:D:\IDEA\IntelliJ IDEA 2018.3.2\lib\idea_rt.jar=58048:D:\IDEA\IntelliJ IDEA 2018.3.2\bin" -Dfile.encoding=UTF-8 -classpath D:\JavaTest\out\production\Test01 zhang.da.pao.Test01
特殊方法
Process finished with exit code 0
总结
向下转型是在调用子类特殊操作的时候考虑使用,但不是所有的操作都适合向下转型。向上转型是向下转型的基础,向上转型实现的是参数类型的统一,向下转型实现的是子类个性化方法调用。