建设银行个人网上银行网站加载,高端自适应网站建设,手机网站锁定竖屏看代码,采集网站后台客户数据OOP(面向对象编程)具有三大特性#xff08;继承、封装、多态#xff09;#xff0c;了解之后总结如下#xff1a;
封装继承向上转型向下转型重写运行时绑定#xff08;动态绑定#xff09;多态
封装
封装的本质是让类的调用者不必太多类的实现者是如何实现类的#x…OOP(面向对象编程)具有三大特性继承、封装、多态了解之后总结如下
封装继承向上转型向下转型重写运行时绑定动态绑定多态
封装
封装的本质是让类的调用者不必太多类的实现者是如何实现类的只知道如何使用类就行了。 public修饰的成员变量或成员方法可以直接被类的调用者使用。 private修饰的成员变量或成员方法不可以直接被类的调用者使用。 当要获取或者修改private属性就需要getter/setter方法了。。注意以下几点
a. getName 即为 getter 方法, 表示获取这个成员的值。 b. setName 即为 setter 方法, 表示设置这个成员的值.。 c. 当set方法的形参名字和类中的成员属性的名字一样的时候如果不使用this, 相当于自赋值. this 表示当前实例的引用。 字段 vs 属性 我们通常将类的数据成员称为 字段(fifield) , 如果该字段同时提供了 getter / setter 方法, 那么我称它为“属性”。
继承
继承is - a的实质就是减少重复代码的出现。用extends关键字进行继承。如 A extends B:那么B就称为父类基类或超类A就称为子类派生类。Java中的继承是单继承。
那么子类到底继承了父类什么呢 子类继承了父类除了构造函数外的所有。子类继承了父类子类需要帮助父类进行构造。 我觉得这句话是太太太重要了以下都是围绕这句话展开。
首先子类继承了父类public的字段和方法。对于父类的privata的字段和方法子类是无法访问的。 protected修饰的字段和方法子类是可以访问的。
子类不能继承父类的构造方法因此要帮助父类进行构造就引入了super关键字super可以调用父类的构造方法必须放在第一行因为构造子类必须先要构造父类。
如果在继承关系中加入代码块它们的执行顺序父类的静态代码块 (执行一次) 子类的静态代码块(执行一次) 父类实例代码块 父类构造代码块 子类实例代码块 子类构造代码块
向上转型 向上转型是从子类--父类那也就是一个较专用类型向较通用类型转换因此比较安全。
public class Animal {protected String name;public Animal(String name) {this.name name;}public void eat() {System.out.println(吃饭饭); }
}class Cat extends Animal {public Cat(String name) {//使用super调用父类的构造方法super(name);}
}class Bird extends Animal {public Bird(String name) {super(name);}public void fly() {System.out.println(飞飞飞);}
}若执行
Aniamls bird new Bird(二哈)
就是向上转型即父类 Aniamls引用子类的 Bird对象。
向上转型发生的时机 1、直接赋值 Animal animal new Bird(二哈);animal.x;
此时要注意animal是父类的引用它只能调用自己的方法或者访问自己的属性。 虽然animal此时是Bird的一个引用但是编译器是以animal的类型Animal来查看有哪些方法的。 即编译器检查有哪些方法存在看的是Animal这个类型 执行时究竟执行父类的方法还是子类的方法看的是Bird这个类型
若animal访问Bird中的方法会产生ClassCastExceptin(类转型异常)若一定要执行那就要进行强制类型转换了。见向下转型。 2、方法传参
public class Test {public static void main(String[] args) {Bird bird new Bird(二哈);feed(bird);}public static void feed(Animal animal) { //向上转型animal.eat();}
}
3、方法返回
public class Test {public static void main(String[] args) {//向上转型Animal animal findMyAnimal();}public static Animal findMyAnimal() {Bird bird new Bird(二哈);return bird;}
} 向下类型转换
向下类型转换存在不确定性比如你是一个图形类但是不一定是圆形类。对于上面向上转型直接赋值出现的问题我们可以进行强制类型转换来解决。 Animal animal new Bird(二哈); //向上转型Bird bird (Bird)animal; //强制类型转换向下转型bird.x; //x可以是Bird当中的方法
这样虽然可以执行不会报错其实也不是非常靠谱假如存在下面的代码 Animal animal new Cat(咪咪);Bird bird (Bird)animal;bird.x; //x为Bird当中的方法 这样的代码运行时会产生ClassCastExceptin(类转型异常)因为animal其实是Cat对象的一个引用不能转化为Bird对象的。为了解决这个问题我们可以在转型前判断animal本质是不是Bird的实例。因此向下转型的前提条件是向下转型父类已经引用了子类向下转型后的类型的对象。 Animal animal new Cat(咪咪);if(animal instanceof Bird) {Bird bird (Bird)animal;bird.x; //x为Bird当中的方法}
instanceof可以判断一个引用是否是某个类的实例如果是则返回true这时再进行向下转型就比较安全了。
重写
子类实现父类的同名方法并且参数的类型完全相同这种情况称为覆写/重写/覆盖Override
重写要注意 1、static修饰的静态方法不能被重写 2、重写时子类的方法的访问权限必须大于等于父类方法的权限 3、父类方法的权限不能是私有的 4、可以使用override注解来显性指示
重写和重载的区别
重载发生在同一个类中方法名称相同、参数类型或个数不同的方法。对权限没有具体要求 重载在有继承关系的类中方法名称返回值类型参数类型及个数完全相同的方法。并且子类的访问修饰权限必须大于等于子类的访问修饰权限静态方法和私有方法不能被重写。 class Animal {String name;public Animal(String name) {this.name name;}public void eat() {System.out.println(this.name animal eat);}
}class Cat extends Animal {public Cat(String name) {super(name);}Overridepublic void eat() {System.out.println(this.name cat eat);}
}public class TestDemo {public static void main(String[] args) {Animal animal new Cat(花花); //向上转型animal.eat();}
}
运行这段代码我们会发现没有子类没有重写父类的方法时调用的父类的方法eat。当子类重写了父类的方法时运行出来的是子类的eat方法。为什么呢 底层是这样实现的
当我们查看底层代码时编译时确实调用的是Animal的eat()方法运行时是Cat的eat()方法。
运行时多态的原理 1、如果子类没有重写eat方法时调用的确实是父类的eat 2、子类重写父类的方法时编译时还是调用父类的方法。运行时确是子类的方法这个是运行时绑定。 3、在运行时子类方法的地址覆盖了父类方法的地址。导致调用了子类的方法
这就是动态绑定运行时绑定调用某个类的方法究竟执行了父类的方法还是子类的方法要看这个引用究竟指向了父类对象还是子类对象。这个过程是程序运行时决定的不是编译时。
下图所示过程 1、方法表和class对象是和类型是一一对应的 2、方法表是在编译的时候产生的 3、不是所有的对象都在堆上class对象存放的方法区
多态
字面上一种事物的多种形态 代码程序程序层次发生多态的前提是①向上转型②同名覆盖方法③调用同名覆盖方法会发生运行时绑定
使用多态的好处 1、类的调用者对类的使用成本进一步降低 2、能够降低代码的圈复杂度避免使用大量的if-else 3、可扩展能力更强