学习内容:
1.抽象类:
public abstract class Perimeter { public abstract double formula(double i);//没有实现体,是个空方法 //当一个类有抽象方法的时候,该类必须被声明为抽象类,抽象类不一定有抽象方法 //抽象类无法被实例化,当一个抽象类被当做一个参数传入一个方法时,可以将其子类实例化传入方法中,实现默认向上转型 //方法修饰词只能是protected public public void test() { //抽象类中的方法可以是普通方法 System.out.println("非抽象方法"); } }
public class Circle extends Perimeter { double r; public double formula(double r) { //继承的父类如果有抽象方法,必须重写抽象方法,否则该类必须声明为抽象类 double perimeter = Math.PI*r*r; return perimeter; } }
2.接口
接口可看做一种特殊的抽象类
public interface Formula { public static final int a = 0; //接口内成员变量默认且只能为常量 public double perimeter(double i);//抽象方法 default void test() { //JDK1.8开始支持默认方法,默认方法是有方法体的,修饰词只能是static default System.out.println("默认方法"); }; }
public class Square implements Formula{ public double perimeter(double r) { //重写抽象方法 double sum = r*r; return sum; } }
3.接口与抽象类的区别
区别1:
子类只能继承一个抽象类,不能继承多个
子类可以实现多个接口
区别2:
抽象类可以定义
public,protected,package,private
静态和非静态属性
final和非final属性
但是接口中声明的属性,只能是
public static final,且必须被初始化,即只能是常量
区别3:接口修饰词只能是public abstract default(不写) 接口内抽象方法的修饰词只能是 public abstract default(JDK1.8默认方法)
另外,接口可以将方法和类进行剥离,只要实现了接口,就一定能调用接口中的方法
需要定义子类的行为,又要为子类提供共性功能时才选用抽象类;
4.继承关系
public interface Testp { public void test(); } public abstract class Test implements Testp { public abstract void test2(); //虽然父类实现了Testp接口,但其本身是个抽象方法,所以可以不重写接口里的抽象方法 } public class Testson extends Test { public void test2() { System.out.println("重写父类抽象方法"); } public void test() { System.out.println("重写父类引用的接口方法"); //如果抽象父类实现了接口,则接口中的方法也会被继承,同时要重写 }
}
接口之间的继承
public interface F { public void f(); } public interface S extends F{ public void s(); } //类在实现接口S时,要重写f()以及s()
5.多态
Java中多态的代码体现在一个子类对象(实现类对象)既可以给这个子类(实现类对象)引用变量赋值,又可以给这个子类(实现类对象)的父类(接口)变量赋值。
例如方法的重写就是一种多态的体现,另外还有+运算的多态,既可以执行加法,也可以执行字符串拼接。
注意,如果是char与数值类型相加得到的是char字符的ascii值与数值相加后的和。
public class Person { int age; public void walk() { System.out.println("人类行走"); } private void watch() { System.out.println("观看"); } public Person(int age) { this.age =age; } public void prints() { //打印成员变量age System.out.println(this.age); } public void printss() { //打印成员变量s System.out.println(this.s); } int s = 10; public static void main(String[] args) { Person p1 = new Person(9);//向上转型,把student当做person用 Student s = new Student(3); p1 = s; Person p2 = new Person(10); p1.walk();//调用student重写后的方法 p2.walk(); p1.watch();//调用person的方法,所以既可以调用子类重写后的方法,也可以调用父类的私有方法 p1.prints(); //构造器中赋值的成员变量读子类,打印出3 p1.printss();//直接赋值的成员变量读父类,打印出的数据是10 System.out.println(p1 instanceof Student); //判断p1所属类型 } }
public class Student extends Person { public void walk() { System.out.println("学生行走"); } public Student(int age) { super(age); } int s = 5; }
编译时期:参考引用变量所属的类,如果没有类中没有调用的方法,编译失败。
运行时期:参考引用变量所指的对象所属的类,并运行对象所属类中的成员方法。
简而言之:编译看左边,运行看右边。
转型可以理解为:拿上例举例来说,Person p = new Student();,可以理解为人类中的学生,本质是人“类”但同时也是学生,所以调用学生类重写后的方法,但如果是调用类方法,则还是调用Person的类方法。
另外,Object类是所有类的父类,可以由Object类向下强转子类。
向下转型:
需要用父类调用子类特有的方法时,需要向下转型
public class Person { int age; public void walk() { System.out.println("人类行走"); } private void watch() { System.out.println("观看"); } public Person(int age) { this.age =age; } }
public class Student extends Person { public void walk() { System.out.println("学生行走"); } public Student(int age) { super(age); } public void study(){ System.out.println("学习"); } }
class Test { public static void main(String[] args){ Person p = new Student(); System.out.print(p instanceof Student);//判断对象类型 Student s = (Student)p; s.study(); //向下转型可以使用Student独有的方法 } }
6.多态应用
public interface Usb { public void open(); public void close(); } public class Laptop { public void poweron() { System.out.println("笔记本开机"); } public void poweroff() { System.out.println("笔记本关机"); } public void use(Usb usb) { usb.open(); usb.close(); } } public class Mouse implements Usb { public void open() { System.out.println("鼠标连接成功"); } public void close() { System.out.println("鼠标连接断开"); } } public class Keyboard implements Usb { public void open() { System.out.println("键盘连接成功"); } public void close() { System.out.println("键盘连接断开"); } } public class Test { public static void main(String[] args) { Laptop l = new Laptop(); l.poweron(); l.use(new Mouse()); //Usb usb = new Mouse();向上转型,把Mouse对象当做Usb接口用 } }