面向对象编程的重点:
多态:
1·向上转型:
就是说父类引用子类的对象;
例如:
Animal1 animal=new Cat1(); 就称为向上转型
class Cat1 extends Animal1{
public Cat1(String name, int age,String sex) {
super(name,age);//显示调用父类的构造方法
this.sex = sex;
System.out.println("Cat()");
}
public class Test{
public static void main(String[] args) {
Animal1 animal=new Cat1();
}
}
向上转型的表达方式有三种:
1·1直接赋值:
Animal1 animal=new Cat1();
1·2进行传参:
public static void func(Animal animal){
animal.eat();
}
public static void main(String[] args) {
Cat1 cat=new Cat1();
func(cat);
}
1·3方法返回:
public static Animal func(Animal animal){
Cat1 cat=new Cat1();
return cat;
}
注意: 当发生向上转型的时候,父类只能调用自己的方法
2·运行时绑定:
运行时绑定的过程我们称之为多态。通俗易懂的讲,就是在编译的时候用的是父类中的方法,但是在运行时用的是子类的方法,也就是运行时动态绑定
3·多态发生的条件:
3·1 要发生继承
3·2 父类引用子类的对象(也就是发生了向上转型)
3·3 通过父类的引用去调用与父类同名的覆盖方法
4·重写和重载:
4·1:重写:
方法名相同,参数列表相同,返回值相同(Override)
4·2:重载
方法名相同,参数列表不同,返回值不做要求(Overload)
注意:
不是所有对象都放在堆中,class对象是放在方法区中的。
方法表是和类型一 一对应的,而不是和对象对应的(反射)。
5·向下转型:
Animal1 animal1=new Cat1();
animal1.eat();//发生的是向上转型
Animal1 animal2=new Bird();
Bird bird=(Bird)animal2;//发生向下转型
bird.fly();
注意: 向下转型要慎用,一般不用;如果要用向下转型一定要先发生向上转型
6·抽象类:
6·1:关键字:abstract
6·2:包含抽象方法的类我们叫做抽象类:public abstract void draw();
6·3:抽象类不能被实例化,但可以发生向上转型
6·4:抽象类当中可以有抽象方法,也可以有非抽象方法或者成员变量
6·5:产生抽象类就是为了继承
6·6:抽象类被继承后一定要重写抽象方法
6·7:抽象类A继承抽象类B,那么抽象类A可以选择重写抽象方法,也可以选择不重写抽象方法
6·8:抽象方法不可以是private的,不然在重写的时候无法重写,只会报错
7·接口:
7·1:关键字:interface
7·2:接口当中的方法,全部都不能实现,也就是说是没有非抽象方法的
7·3:接口中的方法全是抽象方法,都是默认为public abstract所修饰的方法
public interface IShape {
public abstract void draw();
或者:void draw();
}
7·4:接口中的变量都是public static 这样的静态常量
7·5:接口是不能被实例化的
7·6:存在的意义就是被继承,被实现的;关键字为:implements
7·7:普通类实现接口,接口中的所有方法都得重写
7·8:接口和接口的关系不能是实现,但是可以是继承;因为只要一实现就得重写方法并且实现方法,但是在接口中是全是抽象方法,无法实现
总结: 在java中是单继承体制,要实现多继承,就得通过实现接口;实现接口也就是拓展一些行为出来;继承表示的是is-a的关系,接口就是具有某某特性(接口的扩展能力很强)
拓展:
拓展1:
自定义类型进行比较排序的时候要实现(implements Comparable<>)接口,并且重写compareTo()方法
class Student implements Comparable<Student>{
public String name;
public int age;
public double score;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
@Override
public int compareTo(Student o) {
return this.age-o.age;//传进来的age和你当前对象的age 进行比较即可
//return (int)(this.score-o.score);
//return this.name.compareTo(o.name);//比较字符串的大小A.equal(B)是用来比较字符串是否相等
}
}
拓展2:
克隆接口:(implements Cloneable),在自定义类型克隆的时候,一定要实现接口,并且重写clone()方法
class Money implements Cloneable{
double m=12.9;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable{
public String name;
Money money;
public Person(){
}
public Person(String name) {
this.name = name;
this.money=new Money();
}
@Override
protected Object clone() throws CloneNotSupportedException {//只是克隆了Person,也就是说是一个浅拷贝
Person p=(Person) super.clone();
p.money=(Money) this.money.clone();//再将Money也克隆一次,达到深拷贝。
//return super.clone();//返回的是object是一个对象
return p;
}
}
public class TestIo {
/*克隆:
* */
public static void main(String[] args)throws CloneNotSupportedException {
Person person=new Person("CAOCAO");
Person person1=(Person)person.clone();
person1.money.m=99.9;
System.out.println(person.money.m);//12.9
System.out.println(person1.money.m);//99.9
}
}