JAVA动态绑定机制(非常非常重要)
JAVA动态绑定机制:动态绑定是与运行类型进行绑定
1.当调用对象方法的时候,该方法会和该对象的内存地址/运行类型(也就是与运行类型)绑定(意思就是如:有一个Cat类,Cat类中有一个cay方法,这个方法会和Cat类发生动态绑定)
2.当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
package JAVA面向对象中级部分.encapsulationAndInherit.binding;
public class DynamicBinding {
public static void main(String[] args) {
A a = new B();//向上转型
//当注释了B类中的sum()方法和sum1()方法结果变为了30和20
System.out.println(a.sum());//40 --》30
System.out.println(a.sum1());//30 --》20
}
}
class A{//父类
public int i = 10;
//由于调用方法时,方法会和该对象的内存地址(也就是运行类型)绑定
//由于运行类型是B,所以查找是从B类方法开始查找,要因为B类中的getI()方法,直接返回属性i,属性没有动态绑定机制,因此直接返回20
public int sum(){
return getI()+10;
}
//方法是有动态绑定机制,所以查找时,先从子类B查找,由于B类没有sum1方法,
//继承查找父类,父类有则调用sum1方法,要因为sum1方法返回是属性i,属性没有动态绑定机制直接返回i的值,所以是20
public int sum1(){
return i+10;
}
public int getI(){
return i;
}
}
class B extends A {
public int i = 20;
// public int sum(){
// return i+20;
// }
//
// public int sum1(){
// return i+10;
// }
public int getI(){
return i;
}
}
多态应用
基本介绍:多态数组是数组定义类型为父类类型,里面保存的实际元素类型为子类类型
案例:
1.现有一个继承结构如下:要求创建一个Person对象,2个Student对象和2个Teacher对象,统一放在数组中。并调用msay方法。
2.应用实例升级,如何调用子类特有的方法,比如Teacher有一个teach,Student有一个study怎么调用?
package JAVA面向对象中级部分.encapsulationAndInherit.ployArray;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String say(){
return "姓名:"+name+"\t年龄:"+age;
}
}
package JAVA面向对象中级部分.encapsulationAndInherit.ployArray;
public class Student extends Person{
private double score;
public Student(String name,int age) {
this.setName(name);
this.setAge(age);
}
public Student(String name,int age,double score){
//注意在构造器中使用super和this调用构造器完成初始化,两者只能出一个并且放在第一条语句
super(name,age);
// this(name,age);
this.score =score;
}
public String say(){
return super.say()+"\t成绩:"+score;
}
public void study(){
System.out.println("学生:"+getName()+"正在学习JAVA课程!");
}
}
package JAVA面向对象中级部分.encapsulationAndInherit.ployArray;
public class Teacher extends Person{
private double salary;
public Teacher(String name,int age) {
this.setName(name);
this.setAge(age);
}
public Teacher(String name,int age,double salary){
super(name,age);
this.salary = salary;
}
public String say(){
return super.say()+"\tsalary:"+salary;
}
public void teach(){
System.out.println("老师:"+getName()+"正在教JAVA课程!");
}
}
package JAVA面向对象中级部分.encapsulationAndInherit.ployArray;
public class PloyArray {
public static void main(String[] args) {
Person[] people = new Person[5];
people[0] = new Person("海康",20);
people[1] = new Student("湛江",18,99);
people[2] = new Student("南宁",20,99.9);
people[3] = new Teacher("西安",21,21688);
people[4] = new Teacher("广州",22,22168);
//循环遍历多态数组,调用say
for (int i = 0; i < people.length; i++) {
//person[i]编译类型是Person,运行类型是根据实际情况有JV来判断
// System.out.println(people[i].say());//动态绑定机制
if (people[i] instanceof Student){
Student student = (Student) people[i];
student.study();
}else if (people[i] instanceof Teacher){
Teacher teacher = (Teacher) people[i];
teacher.teach();
}else {
System.out.println(people[i].say());//在类型转换时,范围大的一定要放在后面,要不大的对小范围有接收作用
}
}
}
}
多态参数问题
基本介绍:方法定义的形参类型为父类类型,实参类型允许为子类类型
应用实例1:前面的主人喂动物
应用实例2:
定义员工类Employee,包含姓名和月工资【prvate】,以及计算年工资getAnnual的方法。普通员工和经理继承了员工,经理类多了奖金bonus属性和管理manage方法,普通员工类多了work方法,普通员工和经理类要求分别重写getAnnual方法
测试类中添加一个方法showEmpAnnal(Employee employee),实现获取任何员工对象的年工资,并在main方法中调用该方法【employee.getAnnual()】
测试类中添加一个方法,testWork,如果是普通员工,则调用work方法,如果是经理,则调用manage方法
package JAVA面向对象中级部分.encapsulationAndInherit.ployParameter;
public class PloyParameter {
public static void main(String[] args) {
Worker worker = new Worker("海康", 18168);
testWork(worker);
double v = showEmpAnnual(worker);
System.out.println(v);
System.out.println("=================经理===============");
Manager manager = new Manager("明天", 81688, 100000);
testWork(manager);
double v1 = showEmpAnnual(manager);
System.out.println(v1);
}
public static double showEmpAnnual(Employee employee){
return employee.getAnnual();
}
public static void testWork(Employee employee){
if (employee instanceof Worker){
Worker worker = (Worker) employee;
worker.work();
}else if (employee instanceof Manager){
Manager manager = (Manager) employee;
manager.manage();
}else {
System.out.println("您输入的类型有误!");
}
}
}
package JAVA面向对象中级部分.encapsulationAndInherit.ployParameter;
public class Employee {
private String name;
private double salary;
public Employee() {
}
public Employee(String name,double salary){
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
//计算年工资getAnnual方法
public double getAnnual(){
return salary*12;
}
}
package JAVA面向对象中级部分.encapsulationAndInherit.ployParameter;
public class Worker extends Employee{
public Worker() {
}
public Worker(String name, double salary) {
super(name, salary);
}
//普通员工work方法
public void work(){
System.out.println("普通员工打工干活");
}
public double getAnnual(){
return getSalary()*12;
}
}
package JAVA面向对象中级部分.encapsulationAndInherit.ployParameter;
public class Manager extends Employee{
private double bonus;
public Manager(String name,double salary){
super(name,salary);
}
public Manager(double bonus) {
this.bonus = bonus;
}
public Manager(String name, double salary, double bonus) {
super(name, salary);
this.bonus = bonus;
}
//管理方法
public void manage(){
System.out.println("经理放屁了");
}
public double getAnnual(){
return getSalary()*12 + bonus;
}
}