目录标题
继承 和 多态
继承:对共性的一个抽取,使用extends关键字来实现的
语法:A extends B
A:子类
B:父类
意义:为了代码的复用。
注意:
- 子类继承了父类,那么子类在构造的时候,需要先帮助父类来进行构造,需要在子类的构造方法中,使用super关键字来显示的调用父类的构造方法。
- super和this
- 访问修饰限定符 private 包访问权限 protected public
父类的private修饰的成员变量是否被继承了?
不能被继承。因为
多态:
1.向上转型:父类引用,引用子类对象
2.运行时绑定:通过父类引用,调用父类和子类同名的覆盖方法。
覆盖:覆写,重写
a.方法名称相同
b. 参数列表相同【参数的个数+参数的类型】
c. 返回值相同 【特殊:返回值也可以是协变类型】
注意:
简单列举
4. static方法不能重写
5. private修饰的方法
6. final修饰的方法
7. 子类方法的访问权限要大于等于父类的访问权限
- 编译时绑定:通过函数的重载实现的。编译的时候,会根据你给的参数的个数和类型,在编译期间,确定你最终的调用的一个方法
- 向下转型:不安全的。instanceof
理解多态
package demo1;
class Shape{
public void draw(){
System.out.println("Shape::draw()");
}
}
class Rect extends Shape{
public void draw(){
System.out.println("♦");
}
}
class Flower extends Shape{
public void draw(){
System.out.println("❀");
}
}
public class Test {
public static void drawMap(Shape shape){
shape.draw();
}
public static void main(String[] args) {
Rect rect = new Rect();
drawMap(new Rect());
Flower flower = new Flower();
drawMap(new Flower());
}
public static void main1(String[] args) {
Rect rect = new Rect();
rect.draw();
Shape shape2 = new Flower();
shape2.draw();
}
}
不同的表现形式就是多态。通过一个引用调用同一个方法。
Shape这个引用调用的draw方法可能有不同的表现形式,这种行为就叫做多态
普通方法实现
public static void main(String[] args) {
Rect rect = new Rect();
Flower flower = new Flower();
Triangle triangle = new Triangle();
String[] shapes = {"triangle","rect","triangle","rect","flower"};
for (String s:shapes) {
if(s.equals("triangle")){
triangle.draw();
}else if(s.equals("rect")){
rect.draw();
}else{
flower.draw();
}
}
}
多态方法实现
public class Test {
public static void main(String[] args) {
Rect rect = new Rect();
Flower flower = new Flower();
Triangle triangle = new Triangle();
Shape[] shapes = {triangle,rect,triangle,rect,flower};
for (Shape shape: shapes) {
shape.draw();
}
}
抽象类
抽象类:
- 包含抽象方法的类叫做抽象类
- 什么是抽象方法,一个没有具体实现的方法被abstract修饰
- 抽象类不可以被实例化的,new
- 因为不能被实例化所以这个抽象类只能被继承
- 抽象类当中也可以包含和普通类一样的成员和方法
- 一个普通类继承了一个抽象类,那么这个普通类当中,需要重写所有的抽象方法
abstract class Shape{
public int a;
public void func(){
System.out.println("测试普通方法!");
}
public abstract void draw();//抽象方法
}
class Rect extends Shape{
@Override
public void draw() {
System.out.println("♦");
}
}
class Flower extends Shape {
public void draw(){
System.out.println("❀");
}
}
class Triangle extends Shape {
@Override
public void draw() {
System.out.println("△");
}
}
class Cycle extends Shape {
@Override
public void draw() {
System.out.println("○");
}
}
public class Test {
public static void drawMap (Shape shape){
shape.draw();
}
public static void main(String[] args) {
Shape shape = new Rect();
drawMap(shape);
Cycle cycle = new Cycle();
drawMap(cycle);
}
}
- 抽象类最大的作用就是被继承
- 一个抽象类A如果继承了一个抽象类B,那么这个抽象类A,可以不实现抽象父类B的方法
abstract class Shape{
public int a;
public void func(){
System.out.println("测试普通方法!");
}
public abstract void draw();//抽象方法
}
abstract class A extends Shape{
public abstract void funcA();
}
- 结合第八点,当A类再次被一个普通类继承后,那么A和B这两个抽象类当中的抽象方法必须被重写
abstract class Shape{
public int a;
public void func(){
System.out.println("测试普通方法!");
}
public abstract void draw();//抽象方法
}
abstract class A extends Shape{
public abstract void funcA();
}
class B extends A{
@Override
public void funcA() {
}
@Override
public void draw() {
}
}
- 抽象类不能被fianl修饰,那么抽象方法也不能被fianl修饰
接口
- 使用interface来修饰的,interface IA{}
- 接口当中的普通方法不能有具体的实现,如果非要实现就加上default
- 接口当中可以有static的方法
- 里面的所有的方法都是public的
- 抽象方法默认是public abstract的
package demo3;
interface IShape{
public abstract void draw();//抽象方法
default public void func(){
System.out.println("fafafaf");
}
public static void funcStatic(){
System.out.println("fafa");
}
}
public class Test {
}
-
接口是不可以被通过关键字new来实现的
-
类和接口之间的关系是通过implements来进行实现的
-
当一个类实现一个接口,就必须要重写接口当中的抽象方法
interface IShape{
public abstract void draw();//抽象方法
default public void func(){
System.out.println("fafafaf");
}
// public static void funcStatic(){
// System.out.println("fafa");
// }
}
class Rect implements IShape{
@Override
public void draw() {
System.out.println("♦");
}
@Override
public void func() {
System.out.println("重写接口当中的默认方法");
}
}
- 全部的代码
interface IShape{
public abstract void draw();//抽象方法
default public void func(){
System.out.println("fafafaf");
}
// public static void funcStatic(){
// System.out.println("fafa");
// }
}
class Rect implements IShape{
@Override
public void draw() {
System.out.println("♦");
}
@Override
public void func() {
System.out.println("重写接口当中的默认方法");
}
}
class Flower implements IShape {
public void draw(){
System.out.println("❀");
}
}
class Triangle implements IShape {
@Override
public void draw() {
System.out.println("△");
}
}
class Cycle implements IShape {
@Override
public void draw() {
System.out.println("○");
}
}
public class Test {
public static void drawMap(IShape iShape){
iShape.draw();
}
public static void main(String[] args) {
Rect rect = new Rect();
Flower flower = new Flower();
drawMap(rect);
drawMap(flower);
}
public static void main1(String[] args) {
// IShape iShape = new IShape() {
// }
IShape iShape = new Rect();
iShape.draw();
}
}
- 接口当中的成员变量,默认是public static final 修饰的
为什么报错?
因为子类如果要重写父类的方法的话,子类方法的权限一定要大于等于父类,不加是包访问权限。
10. 当一个类实现一个接口之后,重写这个方法的时候,这个方法必须要加上public
-
一个类可以通过关键字extends继承一个抽象类或者普通类,但是只能继承一个类,同时,也可以通过implements实现多个接口,接口之间用逗号隔开就好
-
接口和接口之间存在什么关系?
接口和接口之间可以使用extends来操作他们的关系 此时这里面意味着扩展
一个接口通过extends扩展了另一个接口的功能。此时当一个类D 通知implements实现了这个接口B的时候,此时重写的方法不仅是B的抽象方法,还有他从C接口,扩展来的功能方法
实现多个接口
package demo3;
class Animal{
protected String name;
public Animal(String name){
this.name = name;
}
}
//不是所有的动物都会飞,所以不能写到animal类当中,如果写到另一个类当中,也不行,
//因为一个类不能继承多个类,所以就有了接口
interface IFlying{
void fly();
}
interface IRunning{
void run();
}
interface ISwimming{
void swimming();
}
class Bird extends Animal implements IFlying{
public Bird(String name) {
super(name);
}
@Override
public void fly() {
System.out.println(this.name + "正在飞");
}
}
class Frog extends Animal implements IRunning,ISwimming{
public Frog(String name) {
super(name);
}
@Override
public void run() {
System.out.println(this.name + "正在跑");
}
@Override
public void swimming() {
System.out.println(this.name + "正在游泳");
}
}
class Duck extends Animal implements ISwimming,IRunning,IFlying{
public Duck(String name) {
super(name);
}
@Override
public void fly() {
System.out.println(this.name + "正在飞");
}
@Override
public void run() {
System.out.println(this.name + "正在跑");
}
@Override
public void swimming() {
System.out.println(this.name + "正在游泳");
}
}
public class Test4 {
public static void runFunc(IRunning iRunning){
iRunning.run();
}
public static void SwimmingFunc(ISwimming iSwimming){
iSwimming.swimming();
}
public static void main(String[] args) {
runFunc(new Duck("鸭子"));
runFunc(new Frog("青蛙"));
}
}
常用接口
- comparable
- comparator
- cloneable
class Student implements Comparable{}
如果自定义的数据类型进行大小的比较,一定要实现可以比较的接口。
package demo4;
import java.util.Arrays;
class Student implements Comparable<Student>{
public int age;
public String name;
public double score;
public Student(int age, String name, double score) {
this.age = age;
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", score=" + score +
'}';
}
//谁调用这个方法谁就是this
@Override
public int compareTo(Student o) {
// if(this.age > o.age){
// return 1;
// }else if(this.age < o.age){
// return 0;
// }else{
// return -1;
// }
return this.age - o.age;//从小到大
//return (int)(this.score - o.score);
//return this.name.compareTo(o.name);
}
}
public class Test {
public static void main3(String[] args) {
Student students1 = new Student(12,"bit",98.9);
Student students2 = new Student(6,"abc",88.9);
// if(students1.compareTo(students2) > 0){
//
// }
System.out.println(students1.compareTo(students2));
}
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student(12,"bit",98.9);
students[1] = new Student(6,"abc",88.9);
students[2] = new Student(18,"zhangsan",18.9);
System.out.println(Arrays.toString(students));
Arrays.sort(students);//默认是从小到大的排序
System.out.println(Arrays.toString(students));
}
public static void main1(String[] args) {
int[] array = {1,21,3,14,5,16};
System.out.println(Arrays.toString(array));
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
}