diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
index 5cad965a2..af1977697 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
@@ -162,16 +162,11 @@ internal class QQImpl(
         TODO("not implemented")
     }
 
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        return other is QQ && other.id == this.id
-    }
-
-    override fun hashCode(): Int = super.hashCode()
+    override fun toString(): String = "QQ($id)"
 }
 
 
-@Suppress("MemberVisibilityCanBePrivate")
+@Suppress("MemberVisibilityCanBePrivate", "DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
 internal class MemberImpl(
     qq: QQImpl,
     group: GroupImpl,
@@ -279,12 +274,9 @@ internal class MemberImpl(
         }
     }
 
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        return other is Member && other.id == this.id
+    override fun toString(): String {
+        return "Member($id)"
     }
-
-    override fun hashCode(): Int = super.hashCode()
 }
 
 internal class MemberInfoImpl(
@@ -600,10 +592,7 @@ internal class GroupImpl(
         image.input.close()
     }
 
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        return other is Group && other.id == this.id
+    override fun toString(): String {
+        return "Group($id)"
     }
-
-    override fun hashCode(): Int = super.hashCode()
 }
\ No newline at end of file
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
index 80c2900bc..dcb80fe9f 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
@@ -74,6 +74,16 @@ interface Contact : CoroutineScope {
      * 而 [QQ] 含义为一个独立的人, 可以是好友, 也可以是陌生人.
      */
     override fun equals(other: Any?): Boolean
+
+    /**
+     * @return `bot.hashCode() * 31 + id.hashCode()`
+     */
+    override fun hashCode(): Int
+
+    /**
+     * @return "QQ($id)" or "Group($id)" or "Member($id)"
+     */
+    override fun toString(): String
 }
 
 suspend inline fun Contact.sendMessage(message: Message) = sendMessage(message.toChain())
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
index a3c2a8ff2..7d1fcdc98 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
@@ -97,11 +97,11 @@ interface Group : Contact, CoroutineScope {
     /**
      * 机器人在这个群里的权限
      *
-     * **MiraiExperimentalAPI**: 在未来可能会被修改
+     * @see Group.checkBotPermission
+     * @see Group.checkBotPermissionOperator
      *
      * @see BotGroupPermissionChangeEvent
      */
-    @MiraiExperimentalAPI
     val botPermission: MemberPermission
 
 
@@ -129,6 +129,7 @@ interface Group : Contact, CoroutineScope {
     /**
      * 让机器人退出这个群. 机器人必须为非群主才能退出. 否则将会失败
      */
+    @MiraiExperimentalAPI("还未支持")
     suspend fun quit(): Boolean
 
     /**