Java抽象类、重写、及接口
11 抽象类
11.1 抽象类
抽象方法:没有方法体的方法,是不具体的,因此称之为抽象方法
抽象类:因为类本身是用于描述某一类事物的,如果该类中的方法有抽象方法的话,就说明该类是不具体的
关键词:abstract
问题:抽象方法能否为静态的?
回答:静态方法可以通过类名直接调用,而抽象方法是没有方法体的,调用就没有任何的意义
问题:抽象方法能否为私有的?
回答:私有的方法只能在当前类中使用,当前类中进行调用,没有任何意义,因为没有方法体
问题:那么应该如何去使用抽象方法?
回答:抽象方法仅仅只是为了定义功能,具体的实现由其子类来实现
注意:子类去继承抽象父类,如果子类不给抽象方法一个具体的方法体,那么该子类也就成了一个抽象类,如果子类要对父类中的抽象方法定义方法体,那就需要重写父类中的抽象方法
问题:抽象方法能否使用final关键字修饰?
回答:不允许的,抽象方法是需要被子类重写的,而final关键字修饰的方法代表最终方法,不能被修改
上述问题总结归纳:
问题:抽象方法不能与哪些关键词共存?为什么?
回答:static、final、private
11.2 方法重写(覆写)
重写的前提:有继承或实现的关系
在不同的类中,方法名相同,参数列表相同,返回值类型一致,子类中的权限修饰符要大于或等于父类中的权限修饰符
面试题:java中的重载和重写有什么区别
@Override,如果方法上有该注解,那就意味着该方法一定是从父类中重写的,如果没有,那么该方法就只是该类中的一个方法而已,此时需要注意的是,如果没有加@override,但是父类中有该方法,虚拟机仍然会认为,该方法为重写的方法,如果父类中没有该方法那就是一个普通方法而已,不会报错
//抽象类
public abstract class CatKinds {
//abstract告诉虚拟机这是一个抽象方法
public abstract void eat() ;
public void climbTree() {
System.out.println("爬树");
}
}
public class Cat extends CatKinds{
总结(普通类和抽象类的区别):
1、抽象类不能直接创建对象的,对象是由子类来创建并使用的
2、抽象类中是有构造器的
3、抽象类中有抽象方法,普通类没有
12 接口
当抽象类中的方法都是抽象方法时,建议将该类转换为接口
jdk1.8之前接口的方法都是抽象方法,变量都是常量,1.8及之后接口可以定义默认方法
关键词:interface/implements
存在的意义:主要是用于定义规范/规则
接口的特点:耦合性低、规范化等等,接口与接口之间可以多继承,类与接口之间可以多实现
例如:电脑上的USB接口,即插即拔式,扩展性强,有规则要求
接口的命名规则:建议首字母以I开头
/**
* 定义数据层所有的功能
* 接口中定义的都是功能--定义规范,没有具体实现
*/
public interface ItemsDao{
//添加商品
public abstract void insertItem();
//修改
public abstract void updateItem();
//删除
public abstract void deleteItem();
//查询
public abstract void queryItems();
}
//实现类在实现接口后要求要重写父类中的所有方法
public class ItemsDaoImpl implements ItemsDao{
包名 | 含义 |
---|---|
dao | 数据层--接口 |
dao.impl | 数据层--实现类 |
service | 业务层 |
service.impl | 业务层--实现类 |
controller/servlet | 控制层 |
utils | 工具类 |
beans | 实体类 |
filter | 过滤器 |
config | 配置 |
疑问:接口中的方法可以有很多,但是在用的时候,可能只用了一部分,那还有必要使用接口吗?
回答:接口中定义的是可能会用到的功能,此时不用不代表以后不用
接口中编码特点:
1、方法的修饰符可省略 public abstract
2、变量修饰符可省略 public static final
类与接口的多实现
interface IA{
public void show();
public void run();
}
interface IB{
public void run();
}
interface IC{
public void method();
}
class Impl implements IA,IB,Ic{
接口之间形成继承体系
interface IC{
public void method();
}
interface IB extends IC{
public void run();
}
interface IA extends IB{
public void show();
}
class Impl implements IA{
接口与接口之间多继承
interface IA extends IB,IC{
public void show();
}
interface IB{
public void run();
}
interface IC{
public void method();
}
class Impl implements IA{
问:java中是否可以多继承?
答:普通类中是不允许多继承的,因为会出现调用不明确的问题,接口和接口之间可以多继承
总结(抽象类和接口之间的区别):
1、接口中都是抽象方法,抽象类中还可以有普通方法
2、抽象类中可以有构造器,接口中没有
3、抽象类中定义的是公共的功能,接口中定义的额外的功能
jdk1.8之后,接口中可以有默认方法,是带有方法体的
interface A{
//需要使用default修饰
default void method() {}
}
作业:定义用户管理功能
要求:使用接口和实现类,实现类中有输出语句即可,添加功能需要有数据,具体的数据是从控制台输入得到的
例如:控制台输出四条语句对应增删改查功能,输入1选择添加用户,提示输入用户名和密码,调用实现类中的添加功能输出添加成功
/**
* 用户实体类
*/
public class User {
private int uid;
private String username;
private String password;
public User() {}
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public User(int uid, String username, String password) {
super();
this.uid = uid;
this.username = username;
this.password = password;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
/**
* 接口:定义规则--有哪些功能,功能需要的参数、返回值
*/
public interface IUserDao {
/**
* 添加用户
* @return
* 0 添加失败
* 1 添加成功
*/
public int insertUser(User user);
/**
* 修改用户信息
* @return
*/
public int updateUser(User user);
/**
* 删除用户
*/
public int deleteUser(int uid);
/**
* 查询数据
*/
public void queryUsers();
}
/**
* 根据接口中定义的规则,来做具体的功能实现
*/
public class UserDaoImpl implements IUserDao {
/**
* 程序入口
*/
public class HomeWork {
public static void main(String[] args) {
init();
}
/**
* 初始化方法
*/
public static void init() {
System.out.println("1、添加用户");
System.out.println("2、修改用户");
System.out.println("3、删除用户");
System.out.println("4、查询用户");
System.out.println("5、退出");
System.out.println("请输入编号选择功能:");
operate();
}
/**
* 功能操作
*/
public static void operate() {
//获取用户输入
Scanner scan = new Scanner(System.in);
int inputNum = scan.nextInt();
switch(inputNum) {
case 1:
insertOperate();
break;
case 2:
updateOperate();
break;
case 3:
deleteOperate();
break;
case 4:
queryOperate();
break;
case 5:
System.out.println("再见来不及握手");
break;
}
}
/**
* 添加用户
*/
public static void insertOperate() {
System.out.println("请输入用户名:");
Scanner