super关键字
-
访问父类的属性,但不能访问父类的private属性 super.属性名
-
访问父类的方法,但不能访问父类的private方法 super.方法名(参数列表)
public void ok(){ super.test100; super.test200;//不能访问父类的私有方法 }
-
调用父类的构造器,当子类有和父类的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super,this直接访问是效果一样的
//希望调用父类-A的cal方法 public void sum(){ cal();//找cal方法是,顺序是,先找本类,如有有就调用,没有的话,找父类...指到父类,提示:如果找到的是private是私有的 则报错 this.cal();//等价与cal(); super.cal();//找cal的方法是直接查找父类,跳过本类,其他一样 }
-
如果有多个基类(多个上级),使用super去访问遵循就近原则,当然也要遵循访问权限。
方法重写
子类有一个方法,和父类的某个方法的名称,返回类型,参数一样
细节:
-
方法名和参数必须一样
-
子类的返回类型和父类的返回类型一样,或者是父类返回类型的子类 比如 父类返回类型是object,子类的返回类型是String
public object getInfo(){} public String getInfo(){}
-
子类不能缩小父类的访问权限;public>protected>默认>private
重载与重写的比较
名称 | 发生范围 | 方法名 | 形参列表 | 返回类型 | 修饰符 |
---|---|---|---|---|---|
重载 | 本类 | 必须一样 | 类型,个数或则顺序不一样 | 无要求 | 无要求 |
重写 | 父子类 | 必须一样 | 相同 | 子类重写的方法,返回类型和父类返回类型一致,或者是其子类 | 子类方法不能缩小父类的方法的访问范围 |
多态
-
方法的多态,重载和重写就体现了多态
-
对象的多态:
一个对象的编译类型和运行类型可以不一致
编译类型在定义对象时,就确定了,不能改变
运行类型是可以变化的
编译类型看定义是=号左边,运行类型看=右边
Animal animal=new Dog(); annimal=new Cat;
-
多态的前提是两个对象存在继承的关系;
-
多态是向上转型,父类引用指向子类的对象
语法:父类类型 引用名=new 子类类型();
-
可以调用父类的中的所有成员,但不能调用子类的特有的成员,因为在编译阶段,能调用那些成员,是由编译类型来决定的(也要遵循访问权限)
-
最终的运行效果看子类的具体实现,即调用方法时,按照从子类开始查找方法,然后调用
-
多态的向下转型,子类类型 引用名=(子类类型) 父类引用;
要求父类的引用必须指向的是当前目标类型的对象
当向下转型后,可以调用子类类型中的所有的成员
动态绑定机制
当调用对象方法时,该方法会和该对象的内存地址/运行类型绑定
当调用对象的属性时,没有动态绑定机制,哪里声明,哪里使用
class A{//父类 public int i=10; public int sum(){ return get()+10; } public int sum1(){ return i+10; } public int get(){ return i; } } class B extends A{//子类 public int i=20; public int sum(){ return i+20; } public int get(){ return i; } public int sum1(){ return i+10; } } //main方法中 A a=new B(); System.out.println(a.sum());//40//当我们注销子类中的sum方法时,我们的程序就会去父类找,这是发现return中有个get()方法,子类和父类都有,那我们调用谁呢,这是动态绑定机制就来了,当调用对象方法时,该方法会和该对象的内存地址/运行类型绑定, System.out.println(a.sum1());//30//当我们注销子类的sum1时,这是就会找出发继承机制,发现父类有,属性没有动态绑定访问机制,哪里声明就哪里使用
多态 数组
public class Person {//父类 private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; }//构造器 public String getName() {} public void setName(String name) {} public int getAge() {return age;} public void setAge(int age) { this.age = age;}//get和set方法 public String say(){ return name+"\t"+age; }
public class Student extends Person{//子类 private double score; public Student(String name, int age, double score) { super(name, age);this.score = score;}//构造器 public double getScore() { return score;} public void setScore(double score) {this.score = score;} public String say(){ return "学生"+super.say()+score;} public void study(){System.out.println("学生"+getName()+"整在学习"); }}
public class Teacher extends Person{}//添加一个salary属性,构造器,set和get public String say(){ return "老师"+super.say()+salary; } public void teach(){ System.out.println("老师"+getName()+"正在授课"); }
public class PloyArray { public static void main(String[] args) { Person[] person =new Person[5]; person[0]=new Person("jack",17); person[1]=new Student("jack",18,100); person[2]=new Student("Tom",18,90); person[3]=new Teacher("smith",30,25000); person[4]=new Teacher("king",50,35000); //循环遍历多态数组,调用say方法 for (int i = 0; i < person.length; i++) { //person类型是编译是Person,运行类型是根据实际情况有jvm判断 //动态绑定机制 System.out.println(person[i].say()); // person[i].teach(); 错误:person的编译类型是Person类,没有teach方法 if (person[i] instanceof Student){ Student student=(Student)person[i];//向下转型 student.study(); }else if(person[i] instanceof Teacher){ Teacher teacher=(Teacher)person[i]; teacher.teach(); }else{ System.out.println("类型有误,请自己检查"); } } } }
多态 参数
参考:
package com.jiang.base.encapsulation.polymorphic.polyparameter;
equals
==和equals的比较
-
==是比较运算符,既可以判断基本类型,又可以判断引用类型。
-
== 如果判断基本类型,判断的是值是否相等,
int i=10;double=10.0
-
==如果判断引用类型,判断的是地址是否相等
class A{} A a=new A(); A b=a; A c=b; 判断a==c;即true
class B{} class A extends B{} B bodj=a; 判断 bodj==c;即true
-
equals是Object类中的方法,只能判断引用类型
-
默认判断的是地址是否相等,子类的中往往重写方法,用于判断是否相等