这一块的内容主要是有关Java中的抽象类、接口,以及形式参数与返回值。
抽象类
概述:
用之前的猫狗、动物举例,动物中不应该具体的东西,而且动物中的吃方法、睡觉方法这些等都不应该也是具体,我们把一个不具体的功能称之为抽象的功能,也叫做抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
抽象类的使用代码举例:
abstract class Animal{
// public abstract void eat(){} //这样写会报错,因为抽象方法不能有主体
public abstract void eat();
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
}
abstract class Dog extends Animal{};
public class AbstractDemo {
public static void main(String[] args) {
// Animal a = new Animal(); //Animal是抽象的,无法实例化
Animal a = new Cat();
a.eat();
}
}
//猫吃鱼
特点:
-
抽象类和抽象方法必须使用abstract关键字修饰
格式:abstract class 类名 {} -
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
-
抽象类不能实例化
那么,抽象类如何实例化呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态 -
抽象类的子类
- 要么是抽象类,不需要重写父抽象类的抽象方法
- 要么重写抽象类中所有的抽象方法,那么这个时候子类是一个具体的类
-
成员变量:可以是变量,也可以是常量
-
构造方法:有。可以有构造方法,但是抽象类又不能具体实例化,有什么用呢
用于子类访问父类的初始化 -
成员方法:可以是抽象方法,也可以不是抽象方法
-
如果抽象类中包含成员方法是抽象方法,那么就需要强制具体子类去重写
-
如果抽象类中包含成员方法是非抽象方法,那么继承的子类可以不去调用,提高了代码的复用性
代码举例:抽象类中的成员方法是抽象方法,就需要强制子类重写;如果是非抽象方法,继承的子类可以不去调用
abstract class Animal2{
public int num = 10;
public final int num2 = 20;
public Animal2(){}
public Animal2(String name,int age){}
public abstract void show();//抽象类中的抽象方法,就需要子类去强制重写
public void show2(){//抽象类中的非抽象方法,继承的子类可以不去调用
System.out.println("这是抽象类中一个具体的方法");
}
}
class Dog2 extends Animal2{
public void show(){
System.out.println("这是Dog2类继承Animal2");
}
}
public class AbstractDemo2 {
public static void main(String[] args) {
Animal2 a = new Dog2();
a.num = 100;
System.out.println(a.num);
// a.num2 = 200;//无法改变final修饰的变量
System.out.println("*****************************");
a.show();
a.show2();
}
}
//100
// *****************************
// 这是Dog2类继承Animal2
// 这是抽象类中一个具体的方法
猫狗案例练习:
具体事物:猫、狗
共性:姓名、年龄、吃饭
分析:从具体到抽象
猫:
成员变量:姓名、年龄
构造方法:无参构造、带参构造
成员方法:吃饭(猫吃鱼)
狗:
成员变量:姓名、年龄
构造方法:无参构造、带参构造
成员方法:吃饭(狗吃肉)
通过上面的分析,我们可以看到,这其中有一些共性的内容,所以我们提取出一个父类:Animal类,但由于吃饭的内容不同,所以就定义为抽象方法,由于吃饭是抽象方法,所以Animal类就必须要是抽象类
抽象动物类:
成员变量:姓名、年龄
构造方法:无参、有参
成员方法:抽象的吃饭方法 吃饭()
实现:从抽象到具体代码的实现
动物类:
成员变量:姓名、年龄
构造方法:无参、有参
成员方法:抽象的吃饭方法 吃饭()
狗类:
继承自动物类
无参、有参
重写方法
猫类:
继承自动物类
无参、有参
重写方法
abstract class Animal3{
//姓名
private String name;
//年龄
private int age;
public Animal3(){}
public Animal3(String name,int age){
this.age = age;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//抽象的eat方法
public abstract void eat();
}
class Cat3 extends Animal3{
public Cat3(){}
public Cat3(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("猫吃鱼");
}
}
class Dog3 extends Animal3{
public Dog3(){}
public Dog3(String name,int age){
super(name, age);
}
public void eat(){
System.out.println("狗吃肉");
}
}
public class AbstractTest {
public static void main(String[] args) {
Dog3 dog3 = new Dog3();
dog3.setAge(21);
dog3.setName("张三");
System.out.println(dog3.getName()+"------"+dog3.getAge());
dog3.eat();
Dog3 dog31 = new Dog3("李四", 22);
System.out.println(dog31.getName()+"------"+dog31.getAge());
dog31.eat();
Animal3 a = new Dog3();
a.setName("王五");
a.setAge(23);
System.out.println(dog31.getName()+"-------"+dog31.getAge());
dog31.eat();
Animal3 a1 = new Cat3("赵六",24);
System.out.println(a1.getName()+"-------"+a1.getAge());
a1.eat();
}
}
//张三------21
//狗吃肉
//李四------22
//狗吃肉
//李四-------22
//狗吃肉
//赵六-------24
//猫吃鱼
-
一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
抽象类里面可以没有抽象方法
不能创建对象 -
abstract不能和哪些关键字共存
- private 冲突
- final 冲突
- static 冲突
代码举例 abstract 和private、final、static都冲突:
abstract class Fu{
// public abstract void show();
//Error:(7, 27) java: 非法的修饰符组合: abstract和private
// private abstract void show1();
//Error:(10, 25) java: 非法的修饰符组合: abstract和final
// final abstract void show3();
//Error:(14, 26) java: 非法的修饰符组合: abstract和static
// static abstract void show4();
public static void show5(){
System.out.println("这是一个静态方法");
}
}
class Zi extends Fu{
public static void show5(){
System.out.println("这是继承的一个静态方法");
}
}
public class AbstractDemo3 {
public static void main(String[] args) {
Fu f = new Zi();
f.show5();
Fu.show5();
}
}
//这是一个静态方法
//这是一个静态方法
接口
牢记接口是来做额外的动作的,来体现事物的扩展性
-
接口的特点
- 接口用关键字interface表示
格式:interface 接口名 {} - 类实现接口用implements表示
格式:class 类名 implements 接口名 {} - 接口不能实例化
那么,接口如何实例化呢
按照多态的方式,由具体的子类实例化,这也是多态的一种,接口多态 - 接口的子类
要么是抽象类
要么重写接口中所有的抽象方法
- 接口用关键字interface表示
-
由此可见
- 最常见的是接口多态
- 抽象类多态
- 具体的类多态
一个简单的接口举例:(可以理解为,使用接口,为cat猫类加了一个新的方法)
//定义一个动物训练接口
interface AnimalTrain{
public abstract void jump();
}
class Cat1 implements AnimalTrain{
public void jump(){
System.out.println("猫跳高");
}
}
public class InterfaceDemo {
public static void main(String[] args) {
// AnimalTrain animalTrain = new AnimalTrain();//抽象类无法实例化
AnimalTrain a = new Cat1();//就可以直接理解为使用接口为cat猫添加了一个新的方法
a.jump();
}
}
//猫跳高
- 接口成员的特点:
成员变量:只能是常量,并且是静态的
它里面默认有修饰符:public static final
建议:全部手动给出
构造方法:接口里面没有构造方法
成员方法:只能是抽象方法,没有方法体
默认修饰符是:public abstract
建议:全部手动给出 - 注意:虽然接口里面没有构造方法,但是,所有的类都默认继承一个类:Object,Object是类Object结构的根,每个class都有Object作为超类,所有对象(包括数组)都实现了这个类的方法
成员接口的成员变量默认修饰符:public static final
成员接口的成员方法默认修饰符:public abstract
代码举例:
interface Inter{
int num1 = 20;
public static final int num = 10;
//接口里面没有构造方法
// public Inter(){}
//接口里面不能带有方法主体
// public void show(){
// System.out.println();
// }
public abstract void show();
}
class InterImpl implements Inter{
//接口的子类,要么是抽象类,要么重写接口中所有的方法
public void show(){
}
//进行初始化要有父类的构造方法,这里调用的是父类Object的无参构造方法
public InterImpl(){
super();
}
}
public class InterfaceDemo2 {
public static void main(String[] args) {
Inter i = new InterImpl();
// i.num1 = 30;//这里所有的成员变量给出的默认修饰符都是 public static final所以是不能修改的
System.out.println(i.num);
}
}
//10
- 类与类
继承关系,只能单继承,但是可以多层继承 - 类与接口
实现关系,可以单实现,可以多实现,还可以在继承一个类的同时实现多个接口 - 接口与接口
没有实现关系,只有继承关系,可以单继承,可以多继承
代码举例:
interface Father{
public abstract void show();
}
interface Mother{
public abstract void show2();
}
interface sister extends Mother,Father{}
class Son extends Object implements Father,Mother{
public void show(){
System.out.println("我是儿子");
}
public void show2(){
System.out.println("我实现mother的接口");
}
}
public class InterfaceDemo3 {
public static void main(String[] args) {
Father f = new Son();
f.show();
((Son) f).show2();
}
}
//我是儿子
//我实现mother的接口
小案例:猫狗案例加上跳高的额外功能
分析:从抽象到具体
猫:
姓名、年龄
吃饭、睡觉
狗:
姓名、年龄
吃饭、睡觉
由于存在共性功能,所以抽象提取一个父的抽象类:
动物:
姓名、年龄
吃饭()
睡觉(){}
猫:继承于动物
狗:继承于动物
由于跳高是一个额外的功能,不是动物特有的,不能放在动物抽象类中,所以定义一个接口
接口:
跳高
部分的猫:实现跳高
部分的狗:实现跳高
实现:从抽象到具体代码实现
代码:
interface Jump{
public abstract void jump();
}
abstract class Animal4{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
Animal4(){}
Animal4(String name,int age){
this.age = age;
this.name = name;
}
abstract void eat();
public void sleep(){
System.out.println("睡觉");
}
}
class Cat4 extends Animal4{
public Cat4(){}
public Cat4(String name,int age){
super(name, age);
}
public void eat(){
System.out.println("猫吃鱼");
}
}
class Dog4 extends Animal4 implements Jump{
public Dog4(){}
public Dog4(String name,int age) {
super(name, age);
}
public void eat(){
System.out.println("狗吃肉");
}
public void jump(){
System.out.println("狗跳高");
}
}
public class InterfaceTest1 {
public static void main(String[] args) {
Animal4 a = new Dog4("张三",21);
System.out.println(a.getName()+"---"+a.getAge());
a.eat();
((Dog4) a).jump();
}
}
//张三---21
//狗吃肉
//狗跳高
形式参数和返回值
形式参数
- 形式参数:
基本数据类型
引用数据类型:
类:实际上需要的是该类的对象
抽象类
接口
类:实际上需要的是该类的对象 代码举例:
class Student3{
public void study(){
System.out.println("好好学习");
}
}
class Student3Demo{
public void fun(Student3 s){
s.study();
}
}
public class StudentTest {
public static void main(String[] args) {
Student3 student3 = new Student3();
Student3Demo student3Demo = new Student3Demo();
student3Demo.fun(student3);
}
}
//好好学习
- 形式参数:
基本数据类型
引用数据类型:
类:实际上需要的是该类的对象
抽象类:当抽象类作为形式参数传入方法的时候,需要的是该抽象类的子类对象
接口
抽象类:当抽象类作为形式参数传入方法的时候,需要的是该抽象类的子类对象 代码举例
abstract class Person3{
public abstract void study();
}
class PersonDemo{
public void fun(Person3 p){
p.study();
}
}
class Student4 extends Person3{
public void study(){
System.out.println("学生学习");
}
}
public class PersonTest {
public static void main(String[] args) {
// Person3 person3 = new Person3();//抽象类不能实例化
Student4 student4 = new Student4();
Person3 p =new Student4();
PersonDemo personDemo = new PersonDemo();
personDemo.fun(student4);
personDemo.fun(p);
}
}
//学生学习
//学生学习
- 形式参数:
基本数据类型
引用数据类型:
类:实际上需要的是该类的对象
抽象类:当抽象类作为形式参数传入方法的时候,需要的是该抽象类的子类对象
接口:当接口作为形式参数传入方法的时候,需要的是该接口具体的实现类对象
接口:当接口作为形式参数传入方法的时候,需要的是该接口具体的实现类对象
代码举例:
interface Person6{
public abstract void study();
}
class Person6Demo{
public void fun(Person6 p){
p.study();
}
}
class Teacher6 implements Person6{
public void study(){
System.out.println("老师学习");
}
}
public class TeacherTest {
public static void main(String[] args) {
Teacher6 teacher6 = new Teacher6();
Person6Demo person6Demo = new Person6Demo();
person6Demo.fun(teacher6);
}
}
//老师学习
返回值
- 返回值类型:
基本数据类型
引用数据类型
类:当一个类作为返回值类型的时候,需要的是该类的对象
抽象类
接口
类:当一个类作为返回值类型的时候,需要的是该类的对象 代码举例:
class Student7{
public void study(){
System.out.println("好好学习");
}
}
class Student7Demo{
public Student7 getStudent7(){
// return new Student7();
Student7 student7 = new Student7();
return student7;
}
}
public class StudentTest2 {
public static void main(String[] args) {
Student7Demo student7demo = new Student7Demo();
Student7 student7 = student7demo.getStudent7();
student7.study();
}
}
//好好学习
- 返回值类型:
基本数据类型
引用数据类型
类:当一个类作为返回值类型的时候,需要的是该类的对象
抽象类:当抽象类作为返回值类型的时候,需要的是该抽象类的子类对象
接口
接口类:当一个类作为返回值类型的时候,需要的是该类的对象
abstract class Person7{
public abstract void study();
}
class Doctor7 extends Person7{
public void study(){
System.out.println("医生学习");
}
}
class Person7Demo{
public Person7 getPerson(){
Person7 p = new Doctor7();
return p;
}
}
public class PersonTest2 {
public static void main(String[] args) {
Person7Demo person7Demo = new Person7Demo();
Person7 p = person7Demo.getPerson();
p.study();
}
}
//医生学习
- 返回值类型:
基本数据类型
引用数据类型
类:当一个类作为返回值类型的时候,需要的是该类的对象
抽象类:当抽象类作为返回值类型的时候,需要的是该抽象类的子类对象
接口:当接口作为返回值类型的时候,需要的是该接口实现类的对象
接口:当接口作为返回值类型的时候,需要的是该接口实现类的对象 代码举例:
interface PlayGame{
public void playGame();
}
class PlayGameDemo{
public PlayGame getPlayGame(){
PlayGame p = new Teacher7();
return p;
}
}
class Teacher7 implements PlayGame{
public void playGame(){
System.out.println("玩游戏");
}
}
public class TeacherTest2 {
public static void main(String[] args) {
PlayGameDemo playGameDemo = new PlayGameDemo();
PlayGame p = playGameDemo.getPlayGame();
p.playGame();
}
}
//玩游戏
感谢阅读,我是啊帅和和,一位大数据专业即将大四学生,祝你快乐。