简体   繁体   English

为什么推荐把扩展Room Database的class抽象出来?

[英]Why is it recommended to make the class that extends Room Database to abstract?

What is the reason behind it?其背后的原因是什么? Is it for performance or compulsion?是为了表现还是强迫? Please Explain请解释

When a class extends an abstract class, it needs to override all its abstract methods.当一个 class 扩展一个抽象 class 时,它需要覆盖它的所有抽象方法。 But, in our case we don't need to implement abstract methods of RoomDatabase class. So, to overcome that we need to make our Room database class abstract.但是,在我们的例子中,我们不需要实现RoomDatabase class 的抽象方法。因此,为了克服这个问题,我们需要将 Room 数据库 class 抽象化。

abstract class ABC{
public abstract void methodA();
public abstract void methodB();
public abstract void methodC();
}

public class OurClass extends ABC{
public void methodA(){
System.out.println("Only methodA implementation");
}
}    

This will give compile time error.这将给出编译时错误。

Solution 1: Implement all abstract methods of the Parent class in SubClass.方案一:在SubClass中实现Parent class的所有抽象方法。

Solution 2: (Our case) Make SubClass abstract.解决方案 2:(我们的案例)使 SubClass 抽象。

Because Room provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. 因为Room在SQLite上提供了一个抽象层,以允许流利的数据库访问,同时利用SQLite的全部功能。

Room is an ORM, Object Relational Mapping library. Room是一个ORM,对象关系映射库。 In other words, Room will map our database objects to Java objects. 换句话说,Room将我们的数据库对象映射到Java对象。 Room provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. Room在SQLite上提供了一个抽象层,以允许流利的数据库访问,同时利用SQLite的全部功能。

Because RoomDatabase has defined methods, the inheriting class cannot be an interface. 由于RoomDatabase已定义方法,因此继承的类不能是接口。 And because you write your undefined method in that abstract class, it cannot be a class. 并且因为您在该抽象类中编写了未定义的方法,所以它不能是一个类。

public interface MyDatabase extends RoomDatabase // extend is not allowed for interface

public class MyDatabase extends RoomDatabase {

     public abstract MyDao myDao(); // abstract method is not allowed for non abstract class

}

First, we need to understand one thing about Abstract Classes in that they allow you to skip implementing some default methods of the parent class .首先,我们需要了解抽象类的一件事,因为它们允许您跳过实现父类的一些默认方法

Unlike Interfaces where you implement all the interface methods, in Abstract Classes world the child classes can choose to implement what is specific to the child class and leave out the other implementations if not needed.不像Interfaces ,你实现所有的接口方法,在抽象类中世界的子类可以选择实现什么是特定的子类,并离开了其他实现,如果没有必要的。

If you do a deep dive on the parent RoomDatabase documentation you will note that it is the Base class for all Room databases and it has some methods not relavant to the child classes eg createOpenHelper() , createInvalidationTracker() , clearAllTables() .如果您深入研究 RoomDatabase 父文档,您会注意到它是所有 Room 数据库基类,并且它有一些与子类createOpenHelper()方法,例如createOpenHelper()createInvalidationTracker()clearAllTables()

In fact the docs clearly mention that 'RoomDatabase provides direct access to the underlying database implementation but you should prefer using Dao classes' .事实上,文档清楚地提到'RoomDatabase 提供对底层数据库实现的直接访问,但您应该更喜欢使用 Dao 类'

In simple terms, you should mark your RoomDatabase class as Abstract to enable your class become flexible and skip implementing unnecessary methods of the RoomDatabase Base Class.简单来说,您应该将 RoomDatabase 类标记为Abstract以使您的类变得灵活并跳过实现 RoomDatabase 基类的不必要方法。

This is true because when you don't mark the class as Abstract, you will get an error and Android Studio will prompt you to implement the above Base Class methods.确实如此,因为当您不将类标记为 Abstract 时,您会收到错误消息,Android Studio 会提示您实现上述 Base Class 方法。

So in Kotlin you will do something like this:所以在 Kotlin 中你会做这样的事情:

@Database(entities = [Note::class], version = 1)
abstract class NoteDatabase :RoomDatabase() {
    
    //Property must be initialized or be abstrac
 abstract val noteDAO:NoteDAO
 
}

Here the NoteDatabase inherits from RoomDatabase to make it a RoomDatabase Object- it doesn't need parent's default implementations therefore it skips those because it is marked with Abstract.这里NoteDatabase继承自 RoomDatabase 使其成为 RoomDatabase 对象 - 它不需要父级的默认实现,因此它跳过那些,因为它被标记为抽象。

NoteDatabase only needs to declare the an abstract noteDao variable. NoteDatabase 只需要声明一个抽象的noteDao变量。 This is so that NoteDatabase knows about DAO Interface and this variable is also used for testing.这是为了让 NoteDatabase 知道 DAO 接口,并且这个变量也用于测试。

Consider using abstract classes if any of these statements apply to your situation:如果这些陈述中的任何一个适用于您的情况,请考虑使用抽象类:

  • You want to share code among several closely related classes.您希望在几个密切相关的类之间共享代码。<\/li>
  • You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private).您希望扩展抽象类的类具有许多公共方法或字段,或者需要公共以外的访问修饰符(例如受保护和私有)。<\/li>
  • You want to declare non-static or non-final fields.<\/strong>您要声明非静态或非最终字段。<\/strong> This enables you to define methods that can access and modify the state of the object to which they belong.<\/strong>这使您能够定义可以访问和修改它们所属对象的状态的方法。<\/strong><\/li><\/ul>"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM