一 抽象

1 为什么抽象

  当父子类具有共性的方法,需要定义在父类中的方法,但是父类无法实现功能,需要由具体的子类来实现,此时需要将父类中定义的共性方法,去掉方法体,变为概念。称这样的方法为抽象方法(没有方法体,能够节省栈内存空间);抽象方法必须定义在抽象类中

// 抽象类

public abstract class Animal {

// 姓名

public String name;

// 年龄

public int age;

// 身高

public int high;

// 抽象方法

public abstract void run();

...

}

2 抽象类和抽象方法的定义格式

public abstract class 类名{

public abstract 返回值类型 方法名 ([参数列表]);

}

3 当父类为抽象类时,子类应实现对应的抽象方法或者将子类变为抽象类

// 抽象父类

public abstract class Animal {

// 姓名

public String name;

// 年龄

public int age;

// 身高

public int high;

// 抽象方法

public abstract void run();

...

}

// 实现父类抽象方法

public class Cat extends Animal{

private String crawl;

// 实现继承的抽象类中的抽象方法

@Override

public void run() {

System.err.println("跑");

}

...

}

// 抽象子类继承抽象父类

public abstract class Cat extends Animal{

...

}

  ① 当前子类重写父类已实现的方法 称之为重写

  ② 当子类中定义父类抽象方法时,称之为实现(implements)

  ③ 抽象类会增加类与类之间的耦合度

二 接口

1 作用:为已存在的类提供该类不具备的方法

  ① 由于java中只支持单继承,为实现多继承的效果,Java中提出类似“多继承的操作”,也就是多实现接口,避免单继承的局限性

  ② 父类只需要定义概念,有具体的子类实现,因此该方法应该是抽象的

  ③ 由于不能实现多继承,需要使用接口来定义抽象方法,由具体的子类实现

2 接口的定义格式

public interface 接口名{

抽象方法;

}

3 例子

// 接口中方法默认为抽象方法,abstract可省略

// 可将访问权限修饰符设置为缺省

public interface Door {

public abstract void open();

void close();

}

public interface Lock {

void on();

void off();

}

// 实现多继承

public class Heart implements Door,Lock{

@Override

public void open() {

System.err.println("打开你的心门");

}

@Override

public void close() {

}

@Override

public void on() {

}

@Override

public void off() {

}

}

4 可定义在接口中的类成员

  ① 成员变量:默认public static final修饰

  ② 成员方法:默认public abstract修饰

  ③ 构造方法:接口中不能有构造方法

5 普通类,接口,抽象类

比较项普通类抽象类接口定义关键字classabstractinterface继承或实现的关键字extendsextendsimplements成员字段常量 变量常量 变量常量构造器既能定义也能实例化只能定义,不能实例化既不能定义也不能实例化成员方法普通方法,静态方法抽象方法,普通方法,静态方法只能定义抽象方法(abstract可以省略)

  ① 当需要继承属性的时候,推荐使用抽象方法;其余都用接口;(便于定义统一的操作规则)

  ② 当继承类和实现接口同时出现的时候,一定是先继承在实现

public class Heart extends Animal implements Door,Lock{

}

三 多态

1 含义

  同一方法可以根据发送对象的不同而采取多种不同的行为方式,即一个对象的实际类型是确定的,但可指向对象的引用类型有很多,可实现动态编译

2 前提

  类与类之间必须是继承关系,否则会报类型转换异常(ClassCastException),子类重写父类方法(static,属于类不能重写,私有方法,final),父类引用指向子类对象(Father f1 =new son();),多态是方法的多态,属性没有多态性

3 例子

// 父类

public class Person {

public void run(){

System.err.println("跑");

};

}

// 子类

public class Student extends Person{

@Override

public void run() {

// 子类重写父类方法

System.err.println("小跑");

}

// 子类特有方法

public void eat(){

System.err.println("吃");

}

}

// 多态测试类

public class Test {

public static void main(String[] args) {

// 对象的实际类型是确定的(指new的对象)

// new Person();

// 但指向的引用类型是可变的

// Student能调用的方法都是自己的或者继承父类的

Student s1 =new Student();

// 父类引用指向子类的类型

// Person父类型,可以指向子类,但不能调用子类特有的方法

Person s2 =new Student();

Object s3 =new Student();

// 在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法

// 父类调用子类中对父类重写的方法,称这个重写的方法为回调函数

s2.run();// 小跑

// 子类继承父类的全部方法 可以输出父类方法和子类方法

// 子类重写父类方法后 执行子类方法

s1.run();

// 对象能执行那些方法,主要看左边的类型,和右边关系不大

// 调用子类特有方法时需要强转,不能直接调用

//s2.eat();// 不可用

s1.eat();// 可用

// 需要强转,强转后可调用子类特有方法

((Student) s2).eat();

}

}

  ①对象是哪个类的对象:看对象前面写的是什么

  ②对象指向哪个类的引用:看new关键字后面的构造器

四 引用数据类型的转换

1 分类

① 向上溯型(向上造型):将子类的构造器赋值给父类的对象,引用数据类型自转

  父类 对象名 = new 子类([参数列表])

② 向下溯型(向下造型):将父类对象构造器赋值给子类对象,俗称引用数据类型强转

  子类 对象名 =(子类) new 父类([参数])

③ 当创建父类对象,想调用子类特有方法时,需要强转

public class Play {

public static void main(String[] args) {

Person person=new Student();

Student student= (Student) person;

((Student) person).eat();

student.eat();

}

}

  这段代码首先创建了一个类型为Person的对象person,并将其实例化为Student类型。这是一种向上转型,因为Student是Person的子类。

  然后,将person对象强制转换为Student类型,并将其赋值给student变量。这是一种向下转型,因为我们知道person对象实际上是Student类型的。

  接下来,通过强制转型的方式调用person对象的eat()方法。由于person对象实际上是Student类型的,所以可以调用Student类中的eat()方法。

  最后,通过student变量直接调用eat()方法,这是因为student变量已经是Student类型,可以直接调用Student类中的方法。

五 instanceof运算符

1 含义:判断指定的对象是否是指定类或其子类对象的运算符,结果一定是布尔型

2 格式 :对象 instanceof 类

public class Play {

public static void main(String[] args) {

Person person=new Person();

if(person instanceof Student){

System.err.println("yes1");

}else if(person instanceof Person){

System.err.println("ok1");

}

Student student=new Student();

if(student instanceof Student){

System.err.println("yes2");

}else if(student instanceof Person){

System.err.println("ok2");

}

}

}

3 详解

   ① 首先定义了一个Person对象,并使用instanceof操作符检查person对象是否属于Student类。由于person对象是Person类的实例,而不是Student类的实例,所以第一个条件不满足,输出"ok1"。

   ② 接着定义了一个Student对象,并使用instanceof操作符检查student对象是否属于Student类。由于student对象是Student类的实例,所以第一个条件满足,输出"yes2"。

   ③ 总结:instanceof操作符用于检查一个对象是否属于某个类或其子类的实例。如果对象是该类或其子类的实例,则返回true;否则返回false。在这段代码中,由于person对象是Person类的实例,而student对象是Student类的实例,所以输出结果分别为"ok1"和"yes2"。

六 多态的好处

1简化业务代码

2 提高代码复用性

3 instanceof 、implements、interface关键字

  ① instanceof :判断指定对象是否是指定类或其子类对象的运算符,结果一定是布尔型

  ② implements:实现的关键字

  ③ interface:定义接口的关键字

4 Java中面向对象的特征

  封装、继承、多态、抽象

5 使用面向对象的好处

  ① 提高代码安全性 – 封装

  ② 简化代码 – 封装(简化主函数)、继承和抽象(简化子类)、多态(简化业务)

  ③ 提高代码重用性(复用性)-- 继承、抽象、多态

  ④ 减低类与类的耦合度-- 封装

好文阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。