25、Java面向对象——抽象类和抽象方法、接口

本文详细介绍了Java中的抽象方法、抽象类、接口及其相互关系。讲解了抽象方法的定义、语法和与普通方法的区别,抽象类的特性以及为何使用抽象类。接着通过代码示例展示了如何创建和使用抽象类以及实现多态。接口作为另一种抽象形式,其特点、定义和实现方式也被详细阐述。最后,对比了抽象类与接口的异同,强调了接口在多继承场景下的重要作用。
摘要由CSDN通过智能技术生成

目录

课前先导

一、抽象方法

1、定义

2、语法格式 

3、抽象方法与普通方法的区别 

二、抽象类 

1、定义

2、语法格式

3、 抽象类和普通类的区别

4、为什么使用抽象类 

三、代码演示 

1、创建抽象类

2、创建抽象类的子类 

3、创建测试类及运行结果

四、利用多态实现抽象类实例化 

五、接口

1、接口定义

2、语法格式 

3、接口的特点 

六、类实现接口

1、语法格式:

2、代码演示 

七、利用多态实例化接口 

 八、接口与抽象类

1、接口与抽象类的相似之处

2、接口与抽象类的区别 

课前先导

前面我们学习了继承,在继承的方法重写中,当父类中的方法不满足子类的需求时,进行方法重写,但我们的父类中我们也给了方法体,但如果整个项目不需要去实现它,那定义的方法体就失去了意义。

一、抽象方法

1、定义

英文单词:      abstract   抽象的

(1)在Java中,当一个类的方法被abstract关键字修饰时,该方法称为抽象方法;

(2)当一个方法被定义为抽象方法后,意味着该方法不会有具体的实现(没有方法体),而是在抽象类的子类中通过方法重写进行实现;

(3)抽象方法没有方法体

2、语法格式 

访问权限修饰符   abstract    返回值类型    方法名(参数列表);

3、抽象方法与普通方法的区别 

(1)抽象方法需要用abstract修饰,普通方法不需要;

(2)抽象方法没有方法体,普通方法有方法体;

(3)抽象方法所在的类必须定义为抽象类,普通方法可以出现在抽象类和普通类;

(4)抽象方法必须要在子类中重写,如果子类不实现(重写),子类要定义为抽象类

(5)抽象方法不可以用private修饰符修饰,普通方法可以;

(6)abstract修饰符和final关键字不能同时使用。

二、抽象类 

1、定义

在Java中,当一个类被abstract关键字修饰时,该类称为抽象类。

2、语法格式

访问权限修饰符   abstract   class  类名{

            //代码块

}; 

3、 抽象类和普通类的区别

(1)抽象类需要用abstract修饰,普通类不用;

(2)抽象类不可以实例化(生成对象),普通类可以实例化;

(3)抽象类中可以包含抽象方法和普通方法,普通类中不能包含抽象方法;

(4)抽象类中可以包含普通类的一切成员;

(5)抽象类不能被密封(使用private).

4、为什么使用抽象类 

在面向对象的概念中,所有的对象都是通过类来描绘的;但反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

 一般我们的父类并没有包含子类的特有的属性和方法,所以父类没有足够的信息来描述子类的对象,所以父类可以定义为抽象类。

抽象类往往用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。

比如我们吃饭,但我们每个人吃的都不一样,吃饭就是抽象的,每个人吃什么是具体的,所以抽象的概念他没有具体的概念,抽象概念的抽象类是不能够实例化的。

就像父类定义了一个方法,父类不需要实现什么方法,但所有子类都有这个共同的方法名且实现的方法体不同,我们就把这个方法定义为抽象方法。

三、代码演示 

1、创建抽象类

(1)我们先创建一个普通类,给它定义一个抽象方法

类和方法都报错了,因为有抽象方法一定是抽象类 

(2)给抽象类中定义一个普通方法 

2、创建抽象类的子类 

(1)我们先创建一个子类

 因为没有重写父类中的抽象方法,所以报错了

 (2)重写父类中的抽象方法,并定义个子类特有的方法

public class Cat extends Animal{
	
	//重写
	@Override
	public void eat() {
	System.out.println("猫吃鱼");
	}
	
	//特有方法
	public void action(){
		System.out.println("练瑜伽");
	}

}

3、创建测试类及运行结果

(1)创建测试类并创建父类的对象

报错了,因为抽象类不能被实例化 

(2)创建子类对象,并调用父类和子类的方法

public class AnimalTest {
	public static void main(String[] args) {
		Cat cat = new Cat();
		cat.show();
		cat.eat();
		cat.action();
	}

}

四、利用多态实现抽象类实例化 

上有政策,下有对策,当我们需要实例化抽象类时,可以通过多态去实现

public class AnimalTest {
	public static void main(String[] args) {
		//向上转型
		Animal animal = new Cat();
		animal.show();
		animal.eat();
		//向下转型
		if(animal instanceof Cat){
			Cat cat = (Cat)animal;
			cat.action();
		}
		
	}

}

  

五、接口

首先我们先了解一下什么是接口:大家先看一下自己的电脑上的USB接口,我们能插U盘、鼠标、键盘.......,虽然插的东西不一样,但插上去都能使用,因为电脑上的接口符合USB的标准;

大家再看一下家里的插座,都是一个品牌的吗?我家有公牛的、德力西的....虽然生产厂家不一样,但都能使用,都能通电,因为他们都符合插座的标准。

1、接口定义

(1)接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用;

(2)Java中的接口更多的体现在对行为的抽象

(3)如果抽象类中所有的方法都是抽象方法,就可以使用接口来表示;

(4)接口可以看做是一个特殊的抽象类,但是接口采用与抽象类完全不同的语法来表示,两者的设计理念也不同。

2、语法格式 

英文单词  :interface  接口、接口程序

public  interface  接口名{

        //常量

        //抽象方法

}

3、接口的特点 

(1)接口用关键字interface修饰;

(2)接口不能实例化(创建对象);

(3)接口是隐士抽象,变量和方法都可以不用abstract,默认添加abstract(默认接口成员是抽象的);

(4)接口的方法是公有的,必须使用public修饰,用其他修饰符修饰会报错,不写修饰符,会默认修饰符是public;

(5)定义变量必须是常量,修饰符必须用public,用其他修饰符会报错,不写修饰符默认是public;变量默认是静态常量,static和final可写可不写;

(6)接口与接口之间可以继承;

(7)接口是多继承,一个接口可以有多个父类。

(1)创建一个接口Animal,在里面定义变量和方法

public interface Animal {
	//定义变量默认是:public static final 数据类型  变量名;
	public static final int A = 1;
	static final int B = 2;
	int C = 3;
//这三种定义格式都行,系统都会默认格式为:public static final 数据类型  变量名;
	
	//定义方法
	//系统会默认方法格式为:public abstract 返回值   方法名(参数列表);
	public abstract void eat();
	public void action();
}

(2)接口与接口之间的继承(extends)

接口是多继承,一个接口可以继承多个父类

再创建个猫科动物接口:Catamount 

public interface Catamount {
	
	public abstract void sleep();

}

创建个猫接口:Cat,同时继承Aniaml接口和Catamount接口

//接口继承接口,用extends
public interface Cat extends Animal,Catamount{

}

六、类实现接口

1、语法格式:

(1)当类实现接口时,必须实现接口中所有的成员,否则类要声明为abstract类;

(2)一个类可以实现多个接口;

(3)类使用implements关键字实现接口。

权限修饰符  class  类名  implements  接口1,接口2,......,接口n{ } 

2、代码演示 

首先我们有三个接口

public interface Animal {
	//定义变量默认是:public static final 数据类型  变量名;
	public static final int A = 1;
	static final int B = 2;
	int C = 3;
//这三种定义格式都行,系统都会默认格式为:public static final 数据类型  变量名;
	
	//定义方法
	//系统会默认方法格式为:public abstract 返回值   方法名(参数列表);
	public abstract void eat();
	public void action();
}
public interface Catamount {
	
	public abstract void sleep();

}
public interface Cat extends Animal,Catamount{

}

(1)我们先用Dog类实现Animal接口

没全部实现接口里的方法,就会报错!!! 

public class Dog implements Animal{

	@Override
	public void eat() {
		System.out.println("狗吃肉");
		
	}

	@Override
	public void action() {
		System.out.println("做俯卧撑");
	}
	
}

测试类及运行结果

public class DogTest {
	public static void main(String[] args) {
		//创建Dog类对象并调用方法
		Dog dog = new Dog();
		dog.eat();
		dog.action();
		dog.fight();
	}

}

 (2)创建Tiger类,同时实现Animal和Catamount两个接口

public class Tiger implements Animal,Catamount{

	@Override
	public void eat() {
		System.out.println("吃水果");
		
	}

	@Override
	public void action() {
		System.out.println("纹身");
		
	}

	@Override
	public void sleep() {
		System.out.println("一天睡八小时");
		
	}
	
	//Tiger类特有方法
	public void dream(){
		System.out.println("烫头");
	}
	
	

}

测试类及运行结果

public class TigerTest {
	public static void main(String[] args) {
		//创建Tiger类对象
		Tiger tiger = new Tiger();
		tiger.eat();
		tiger.action();
		tiger.sleep();
		tiger.dream();
	}

}

 (3)创建Kitten类实现子接口Cat

实现类实现的接口如果有父类,要把所有父类中的方法都实现

public class Kitten implements Cat{

	@Override
	public void eat() {
		System.out.println("小猫吃小鱼干");
		
	}

	@Override
	public void action() {
		System.out.println("玩毛线");
		
	}

	@Override
	public void sleep() {
		System.out.println("一天睡16小时");
		
	}
	

}

测试类及运行结果

public class KittenTest {
	public static void main(String[] args) {
		//创建Kitten对象
		Kitten kitten = new Kitten();
		kitten.eat();
		kitten.action();
		kitten.sleep();
	}

}

七、利用多态实例化接口 

Animal接口

public interface Animal {
	
	public abstract void eat();
	public void action();
}

实现类Dog类 

public class Dog implements Animal{

	@Override
	public void eat() {
		System.out.println("狗吃肉");
		
	}

	@Override
	public void action() {
		System.out.println("做俯卧撑");
	}
	
	//Dog类特有方法
	public void fight(){
		System.out.println("打群架");
	}
	
}

测试类及运行结果 

public class Test {
	public static void main(String[] args) {
		//多态  父类引用指向子类对象
		Animal animal = new Dog();
		animal.eat();
		animal.action();
		
		//向下转型
		if(animal instanceof Dog){
			Dog dog = (Dog)animal;
			dog.fight();
		}
	}

}

 八、接口与抽象类

1、接口与抽象类的相似之处

(1)不能实例化;

(2)包含未实现的方法声明;

(3)派生类必须实现未实现的方法,抽象类时抽象方法,接口则是所有成员(不仅包括方法,还有其他成员)。

2、接口与抽象类的区别 

(1)一个类能实现多个接口,但一个类只能从一个抽象类(或其他类型的类)继承,从抽象类派生的子类,仍然能实现接口,从而得出接口是用来解决多重继承问题的

(2)抽象类中可以存在非抽象的方法,可接口不能,且接口中的方法只是一个声明,必须用public修饰,没有具体实现方法;

(3)抽象方法中的成员变量可以用不同的修饰符来修饰,接口中的成员变量默认是静态常量(static  final)

(4)抽象类是对象的抽象,然而接口是一种行为规范。

越往后学,大家就会慢慢觉得抽象类没什么用,干嘛不直接定义接口呢。它既然存在就一定有它的用法。大家只要记着,抽象方法是单继承,接口是实现多继承的区别就行了。今天的内容有点多,大家学习的时候可以把两个只是点分开学,搞明白它俩的区别,学起来就简单多了。好了,我是一米八、有腹肌、低于半小时你报警的Loveletter,觉得内容不错的小伙伴可以点点关注,我们下篇博文见,再见!

​​​​​​​

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值