Java入门第二季,java第二季
Java入门第二季,java第二季
- 类和对象
- 1 什么是类和对象
- 2 如何定义Java中的类
- 3 如何使用 Java 中的对象
- 4 练习题
- 5 Java 中的成员变量和局部变量
- 6 Java 中的构造方法
- 7 Java 中的 static 使用之静态变量
- 8 练习题
- 9 Java 中的 static 使用之静态方法
- 10 Java 中的 static 使用之静态初始化块
- 封装
- 1 什么是 Java 中的封装
- 2 使用包管理 Java 中的类
- 3 Java 中的访问修饰符
- 4 Java 中的 this 关键字
- 5 什么是 Java 中的内部类
- 6 Java 中的成员内部类
- 7 Java 中的静态内部类
- 8 Java 中的方法内部类
- 9 练习题
- 继承
- 1 Java中的继承
- 2 Java 中的方法重写
- 3 练习题
- 4 Java 中的继承初始化顺序
- 5 Java 中的 final 的使用
- 6 练习题
- 7 Java 中的 super 的使用
- 8 Java 中的 Object 类
- 9 Java 中的 Object 类
- 10 练习题
- 多态
- 1 Java 中的多态
- 2 多态中的引用类型转换
- 3 Java 中的抽象类
- 4 练习题
- 5 Java 中的接口
- 6 练习题
- 7 UML 简介
- 项目实战
- 综合练习
- 类和对象
1 类和对象
1.1 什么是类和对象
属性:有什么
方法:可以干什么
1.2 如何定义Java中的类
package com.amoscxy;
// 1 定义一个类
public class Telphone {
// 2 属相(成员变量)有什么
float screen;
float cpu;
float mem;
// 3 方法 干什么
void call() {
System.out.println("Telphone有打电话的功能!");
}
void sendMessage() {
System.out.println("Telphone有发短信功能!");
}
}
1.3 如何使用 Java 中的对象
package com.amoscxy;
// 1 定义一个类
public class Telphone {
// 2 属相(成员变量)有什么
float screen;
float cpu;
float mem;
// 3 方法 干什么
void call() {
System.out.println("Telphone有打电话的功能!");
}
void sendMessage() {
System.out.println("screen:"+screen+"cup:"+cpu+"mem:"+mem+"Telphone有发短信功能!");
}
}
package com.amoscxy;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
//完成 main 方法
public static void main(String[] args) {
// 创建对象
Telphone telphone = new Telphone();
telphone.sendMessage();
// 给实例变量赋值
telphone.screen=5.0f;
telphone.cpu=1.4f;
telphone.mem=2.0f;
// 调用对象的方法
telphone.sendMessage();
}
}
1.4 练习题
(B)
1.5 Java 中的成员变量和局部变量
1.6 Java 中的构造方法
1.7 Java 中的 static 使用之静态变量
1.8 练习题
(C)
1.9 Java 中的 static 使用之静态方法
1.10 Java 中的 static 使用之静态初始化块
2 封装
2.1 什么是 Java 中的封装
telphone2.setScreen(6.0f);
System.out.println("screen:"+telphone2.getScreen());
private float screen;
public float getScreen() {
return screen;
}
public void setScreen(float screen) {
this.screen = screen;
}
2.2 使用包管理 Java 中的类
package com.amoscxy;
import com.amoscxy.second.Telphone; // 使用新建Telphone类
public class main {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 通过无参构造方法创建对象
Telphone telphone = new Telphone();
}
}
package com.amoscxy.second;
// 新建Telphone类
public class Telphone {
public Telphone() {
// TODO Auto-generated constructor stub
System.out.println("执行了新建类!");
}
}
2.3 Java 中的访问修饰符
C
ABC
2.4 Java 中的 this 关键字
private float screen;
private void sendMessage() {
System.out.println("this sendMessage!");
}
public void setScreen(float screen) {
this.screen = screen; // this.属性
this.sendMessage(); // this.方法
}
2.5 什么是 Java 中的内部类
package com.amoscxy;
public class HelloWorld {
public class Inner{ // 内部类
public void show() {
System.out.println("welcome to imooc!");
}
}
public static void main(String[] args) {
HelloWorld hello = new HelloWorld();
Inner inner = hello.new Inner(); // 生成内部类的对象
inner.show();
}
}
2.6 Java 中的成员内部类
2.7 Java 中的静态内部类
2.8 Java 中的方法内部类
2.9 练习题
(A)
3 继承
3.1 Java中的继承
Java中的继承是单继承:相当于每个人只有一个亲爹
一个人有个好爹就可以少奋斗几年
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog = new Dog(); public属性
// dog.age = 10; // 子类不能直接使用父类的private属性
dog.name = "xiaotian"; // 子类可以直接使用父类的
dog.eat(); // 子类可以直接调用父类的public方法
}
}
package com.amoscxy;
public class Dog extends Animal { // 新建子类Dog继承Animal,没有任何属性和方法
}
package com.amoscxy;
public class Animal { // 父类
private int age;
public String name;
public void eat() {
System.out.println("动物具有吃东西的能力!");
}
}
3.2 Java 中的方法重写
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog = new Dog();
dog.eat(); // 优先执行子类重写的方法
}
}
package com.amoscxy;
public class Dog extends Animal {
public void eat() { // 子类重写父类的方法
System.out.println("狗具有吃东西的能力!");
}
}
package com.amoscxy;
public class Animal { // 父类
private int age;
public String name;
public void eat() { // 父类方法
System.out.println("动物具有吃东西的能力!");
}
}
3.3 练习题
(A)
3.4 Java 中的继承初始化顺序
3.4.1 初始化对象时,先初始化父类再初始化子类
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog = new Dog();
}
}
package com.amoscxy;
public class Dog extends Animal {
public Dog() { // 子类构造方法
// TODO Auto-generated constructor stub
System.out.println("Dog类执行了!");
}
}
package com.amoscxy;
public class Animal {
public Animal() { // 父类构造方法
// TODO Auto-generated constructor stub
System.out.println("Animal类执行了!");
}
}
执行结果:
Animal类执行了!
Dog类执行了!
3.4.2 先执行属性的初始化,再执行构造方法的初始化
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Animal animal = new Animal();
System.out.println("animal age:"+animal.age);
}
}
package com.amoscxy;
public class Animal {
public int age = 10;
public Animal() {
// TODO Auto-generated constructor stub
age = 20;
}
}
执行结果:
animal age:20
3.5 Java 中的 final 的使用
3.5.1 final关键字做标识有“最终”的含义,及不允许被修改
3.5.2 final修饰类,则该类不允许被继承
package com.amoscxy;
public class Dog extends Animal { // bug:The type Dog cannot subclass the final class Animal
}
package com.amoscxy;
final public class Animal { // final修饰类
}
3.5.3 final修饰方法,该方法不允许被覆盖(重写)
package com.amoscxy;
public class Dog extends Animal {
final public void eat() { // bug:Cannot override the final method from Animal
System.out.println("狗具有吃东西的能力!");
}
}
package com.amoscxy;
public class Animal {
final public void eat() {
System.out.println("动物具有吃东西的能力!");
}
}
3.5.4 final修饰属性,则该属性只能被赋值一次,不能在其它位置被修改
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Animal animal = new Animal();
animal.age = 20; // bug:The final field Animal.age cannot be assigned
}
}
package com.amoscxy;
public class Animal {
final public int age =10; // final修饰属性,只能被赋一次值
public Animal() {
// TODO Auto-generated constructor stub
age = 20; // bug:The final field Animal.age cannot be assigned
}
}
3.5.5 final修饰属性,则该属性不会被自动初始化
package com.amoscxy;
public class Animal {
final public int age;
public Animal() { // bug:The blank final field age may not have been initialized
// TODO Auto-generated constructor stub
// age = 20;
}
}
3.5.6 final修饰属性,如果不在声明时初始化,还有个时间点是在构造函数中初始化
package com.amoscxy;
public class Animal {
final public int age;
public Animal() { // bug:The blank final field age may not have been initialized
// TODO Auto-generated constructor stub
age = 20;
}
}
3.5.7 final修饰变量,则该变量只能被赋值一次,不能在其它位置被修改,此时这个变量也称为常量
package com.amoscxy;
public class Animal {
public Animal() {
// TODO Auto-generated constructor stub
final int i;
i = 20;
System.out.println("i:"+i);
}
}
或者:
package com.amoscxy;
public class Animal {
public Animal() {
// TODO Auto-generated constructor stub
final int i = 20;
System.out.println("i:"+i);
}
}
不可以:
package com.amoscxy;
public class Animal {
public Animal() {
// TODO Auto-generated constructor stub
final int i = 20;
i = 10; // bug:The final local variable i cannot be assigned. It must be blank and not using a compound assignment
System.out.println("i:"+i);
}
}
3.6 练习题
(A)
3.7 Java 中的 super 的使用
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog = new Dog();
dog.method();
}
}
package com.amoscxy;
public class Dog extends Animal {
public int age = 20;
public void eat() {
// TODO Auto-generated method stub
System.out.println("狗具有吃骨头的能力!");
}
public void method() {
// TODO Auto-generated method stub
System.out.println("super.age:" + super.age); // 在子类中用super.age调用父类的属性
super.eat(); // 在子类中用super.eat()调用父类的方法
}
}
package com.amoscxy;
public class Animal {
public int age = 10;
public void eat() {
// TODO Auto-generated method stub
System.out.println("动物具有吃东西的能力!");
}
}
输出:
super.age:10
package com.amoscxy;
public class Dog extends Animal {
public Dog() {
// TODO Auto-generated constructor stub
System.out.println("Dog类构造方法执行了!");
super(); // bug:Constructor call must be the first statement in a constructor,即父类的构造方法super()必须放在第一行
}
}
package com.amoscxy;
public class Animal {
public Animal() {
// TODO Auto-generated constructor stub
System.out.println("Dog类构造方法执行了!");
}
}
package com.amoscxy;
public class Animal {
public int age = 10;
public Animal(int age) { // 父类显示定义了有参构造方法,就不会自动生成无参构造方法
// TODO Auto-generated constructor stub
this.age=age;
}
}
package com.amoscxy;
public class Dog extends Animal {
public int age = 20;
public Dog() { // bug:Implicit super constructor Animal() is undefined. Must explicitly invoke another
// TODO Auto-generated constructor stub
System.out.println("Dog类构造方法执行了!");
}
}
3.8 Java 中的 Object 类 Ⅰ
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog = new Dog();
System.out.println(dog);
}
}
package com.amoscxy;
public class Animal { // 没有继承默认继承Object类,Object类中定义了toString()方法返回:包名@类在内存中的地址
public int age = 10;
}
package com.amoscxy;
public class Dog extends Animal { // 父类,没有重写toString()方法
public int age = 20;
}
输出:包名@类在内存中的地址
com.amoscxy.Dog@7852e922
package com.amoscxy;
public class Dog extends Animal {
public int age = 20;
@Override
public String toString() { // 父类重写了toString()方法
return "Dog [age=" + age + "]";
}
}
输出:
Dog [age=20]
3.9 Java 中的 Object 类 Ⅱ
equals()方法返回的是boolean类型,因此可以配合if使用
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog = new Dog();
Dog dog2 = new Dog();
if(dog.equals(dog2)) {
System.out.println("两个对象是相同的!");
}else {
System.out.println("两个对象时不同的!");
}
}
}
package com.amoscxy;
public class Dog extends Animal {
public int age = 20;
}
输出:
两个对象时不同的!
package com.amoscxy;
public class Dog extends Animal {
public int age = 20;
@Override
public boolean equals(Object obj) { // 重写了equals(Object obj)方法
if (this == obj) // 两个引用的地址是否相同则true
return true;
if (obj == null) // 其中一个引用的地址是空值则false
return false;
if (getClass() != obj.getClass()) // 两个类对象不相同则false
return false;
Dog other = (Dog) obj;
if (age != other.age) // 两个类的对象不相同则false
return false;
return true;
}
}
输出:
两个对象是相同的!
类对象与类的对象比较:
类对象:强调的是对象的类型
类的对象:强调的是对象的属性值
3.10 练习题
(A)
4 多态
4.1 Java 中的多态
4.1.1 引用多态:父类引用可以指向子类对象
package com.amoscxy;
public class Initial {
public static void main(String[] args) {
// TODO Auto-generated method stub
Animal ob1 = new Animal(); // 父类的引用指向本类的对象
Animal ob2 = new Dog(); // 父类的引用指向子类的对象
Dog obj3 = new Animal(); // bug:Type mismatch: cannot convert from Animal to Dog;子类应用不可以指向父类对象
}
package com.amoscxy;
public class Animal {
}
package com.amoscxy;
public class Dog extends Animal {
}
4.1.2 方法多态:父类应用指向子类对象,这个引用调用的方法是子类重写的方法
package com.amoscxy;
public class Initial {
public static void main(String[] args) {
// TODO Auto-generated method stub
Animal obj1 = new Animal(); // 父类的引用指向本类的对象
Animal obj2 = new Dog(); // 父类的引用指向子类的对象
Cat obj3 = new Cat();
obj1.eat(); // 执行父类的方法
obj2.eat(); // 执行子类重写的方法
obj3.eat(); // 子类没有重写父类的方法,执行父类中的方法
obj2.watchDoor(); // bug:The method watchDoor() is undefined for the type Animal;父类引用不能调用子类独有的方法
}
}
package com.amoscxy;
public class Animal { // 父类
public void eat() {
// TODO Auto-generated method stub
System.out.println("动物具有吃东西的能力!");
}
}
package com.amoscxy;
public class Dog extends Animal { // 子类1
@Override
public void eat() { // 重写父类中的方法
// TODO Auto-generated method stub
super.eat();
System.out.println("狗具有吃骨头的能力!");
}
public void watchDoor() { // Dog子类独有的方法
// TODO Auto-generated method stub
System.out.println("狗具有看门的能力!");
}
}
package com.amoscxy;
public class Cat extends Animal { // 子类2,没有重写父类中的方法
}
4.2 多态中的引用类型转换
instanceof关键字来验证引用是否是某个类型或者某个类型的子类型
package com.amoscxy;
public class Initial {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog = new Dog();
Animal animal = dog; // 父类引用指向子类对象;自动类型提升/向上类型转换
if(animal instanceof Dog) { // instanceof关键字来验证引用是否是某个类的对象
Dog dog2 = (Dog)animal; // 子类应用指向父类对象;向下类型转换/强制类型转换
}else {
System.out.println("无法进行类型转换 转换成Dog类型!");
}
if(animal instanceof Cat) { // instanceof关键字来验证引用是否是某个类型或者某个类型的子类型
/*
* Exception in thread "main" java.lang.ClassCastException: bug:com.amoscxy.Dog cannot be cast to com.amoscxy.Cat
* 1.编译时是Cat类型 2.运行时是Dog类型
*/
Cat cat = (Cat)animal;
}else {
System.out.println("无法进行类型转换 转换成Cat类型!");
}
}
}
4.3 Java 中的抽象类
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
TelPhone tel1 = new CellPhone();
tel1.call();
tel1.message();
TelPhone tel2 = new SmartPhone();
tel2.call();
tel2.message();
}
}
package com.amoscxy;
public abstract class TelPhone { // 父类是抽象类
public abstract void call(); // 抽象方法没有方法体以分号结束
public abstract void message(); // 抽象方法没有方法体以分号结束
}
package com.amoscxy;
public class CellPhone extends TelPhone { // 子类1
@Override
public void call() { // 自动实现抽象类中的方法
// TODO Auto-generated method stub
System.out.println("通过键盘来打电话!");
}
@Override
public void message() { // 自动实现抽象类中的方法
// TODO Auto-generated method stub
System.out.println("通过键盘来发短信!");
}
}
package com.amoscxy;
public class SmartPhone extends TelPhone { // 子类2
@Override
public void call() { // 自动实现抽象类中的方法
// TODO Auto-generated method stub
System.out.println("通过语音来打电话!");
}
@Override
public void message() { // 自动实现抽象类中的方法
// TODO Auto-generated method stub
System.out.println("通过语音来发短信!");
}
}
输出:
通过键盘来打电话!
通过键盘来发短信!
通过语音来打电话!
通过语音来发短信!
4.4 练习题
(D)
解析:
包含抽象方法的类一定是抽象类,抽象类和抽象方法都需要添加关键字 abstract,且顺序为 abstract class
4.5 Java 中的接口
如果我们没有显示的写出接口的修饰符abstract,系统会自动生成
Java 中接口可以继承多个父接口(多继承),类只能继承一个类(单继承)
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
IPlayGame ip1 = new SmartPhone(); // 接口的引用指向实现了接口的对象
IPlayGame ip2 = new Psp(); // 接口的引用指向实现了接口的对象
ip1.playGame();
ip2.playGame();
}
}
package com.amoscxy;
public abstract class TelPhone { // 抽象父类
public abstract void call(); // 抽象方法没有方法体以分号结束
public abstract void message(); // 抽象方法没有方法体以分号结束
}
package com.amoscxy;
// 接口名通常前面加个I,以便与类做区分
public interface IPlayGame { // 系统自动添加abstract关键字
public void playGame(); // 系统自动添加abstract关键字
}
package com.amoscxy;
public class CellPhone extends TelPhone { // 子类1
@Override
public void call() { // 自动实现抽象类中的方法
// TODO Auto-generated method stub
System.out.println("通过键盘来打电话!");
}
@Override
public void message() { // 自动实现抽象类中的方法
// TODO Auto-generated method stub
System.out.println("通过键盘来发短信!");
}
}
package com.amoscxy;
public class SmartPhone extends TelPhone implements IPlayGame { // 子类2,并实现接口
@Override
public void call() { // 自动实现抽象类中的方法
// TODO Auto-generated method stub
System.out.println("通过语音来打电话!");
}
@Override
public void message() { // 自动实现抽象类中的方法
// TODO Auto-generated method stub
System.out.println("通过语音来发短信!");
}
@Override
public void playGame() { // 实现接口中的方法
// TODO Auto-generated method stub
System.out.println("SmartPhone 具有了玩游戏的功能!");
}
}
package com.amoscxy;
public class Psp implements IPlayGame { // 实现接口
@Override
public void playGame() {
// TODO Auto-generated method stub
System.out.println("Psp 具有了玩游戏的功能!");
}
}
输出:
SmartPhone 具有了玩游戏的功能!
Psp 具有了玩游戏的功能!
package com.amoscxy;
public class Initail {
public static void main(String[] args) {
IPlayGame ip3 = new IPlayGame() { // 使用匿名内部类的方式实现接口,在Android开发和其它高级框架中经常这样使用接口
@Override
public void playGame() {
// TODO Auto-generated method stub
System.out.println("使用匿名内部类的方法实现接口!");
}
};
ip3.playGame();
new IPlayGame() { // 使用匿名内部类的方式实现接口2
@Override
public void playGame() {
// TODO Auto-generated method stub
System.out.println("使用匿名内部类的方法实现接口2!");
}
}.playGame();
}
}
输出:
使用匿名内部类的方法实现接口!
使用匿名内部类的方法实现接口2!
4.6 练习题
(C)
解析:
接口中方法不能有方法体,同时方法的访问修饰符不能是 private 和 protected
4.7 UML 简介
用例图:把角色和系统功能关联在一起
序列图:用户和系统对象的交互环节
5 项目实战
综合练习
package com.amoscxy;
import java.util.Scanner;
public class Rent {
public static void main(String[] args) {
// TODO Auto-generated method stub
Car[] rentCar = {new RCar(1,"奥迪A4 ",500,4),new RCar(2,"马自达6 ",400,4),new RHCar(3, "皮卡雪6 ", 450, 4, 2),new RCar(4, "金龙 ", 800, 20),new HCar(5, "松花江 ", 400, 4),new HCar(6, "依维柯 ", 1000, 20) };
System.out.println("欢迎使用咔咔租车:"+"\n"+"您是否要租车:1是 0否");
Scanner input = new Scanner(System.in);
int answer = input.nextInt();
if(answer == 1) {
System.out.println("您可租车的类型及其价目表:");
System.out.println("序号 汽车名称 租金 容量");
for(Car cars:rentCar) {
cars.List();
}
}
System.out.println("请输入需要租车的数量:");
input = new Scanner(System.in);
int num = input.nextInt();
int[] rentnum = new int[num];
for(int i =1;i<=num;i++) {
System.out.println("请输入第"+i+"辆车的序号:");
input = new Scanner(System.in);
rentnum[i-1] = input.nextInt();
}
System.out.println("请输入租车天数:");
input = new Scanner(System.in);
int day = input.nextInt();
double allprice = 0;
for(int i = 1; i <= num; i++){
allprice += rentCar[rentnum[i-1]-1].price * day;
}
System.out.println("您的账单:");
System.out.println("=====可载人的车有=====");
int allCount = 0, allVolume = 0;
for(int i = 0; i < num; i++){
if(rentCar[rentnum[i]-1] instanceof RCar || rentCar[rentnum[i]-1] instanceof RHCar){
System.out.println(rentCar[rentnum[i]-1].name);
allCount += rentCar[rentnum[i]-1].count;
}
}
System.out.println("共载人:"+allCount+"人");
System.out.println("=====可载货的车有=====");
for(int i=0;i<num;i++){
if(rentCar[rentnum[i]-1] instanceof HCar || rentCar[rentnum[i]-1] instanceof RHCar){
System.out.println(rentCar[rentnum[i]-1].name);
allVolume += rentCar[rentnum[i]-1].volume;
}
}
System.out.println("共载货:"+allVolume+"吨");
System.out.println("------------\n租车总价格为:"+allprice+"元");
}
}
package com.amoscxy;
public abstract class Car { // 基类是抽象类
int num; // 序号
String name; // 名称
double price; // 价格
int volume; // 载货量
int count; // 载人量
public abstract void List();
}
package com.amoscxy;
public class HCar extends Car {
public HCar(int num, String name,double price, int volume) {
// TODO Auto-generated constructor stub
this.num = num;
this.name = name;
this.price = price;
this.volume = volume;
}
@Override
public void List() {
// TODO Auto-generated method stub
System.out.println(this.num+" "+this.name+" "+this.price+"元/天"+" "+"载货:"+this.volume+"吨");
}
}
package com.amoscxy;
public class RCar extends Car {
public RCar(int num, String name, double price,int count) {
this.num = num;
this.name = name;
this.price = price;
this.count = count;
}
public void List() {
System.out.println(this.num + " "+ this.name+" "+ this.price + "元/天" + " 载人:"+this.count + "人");
}
}
package com.amoscxy;
public class RHCar extends Car {
public RHCar(int num, String name,double price,int count,int volume) {
// TODO Auto-generated constructor stub
this.num = num;
this.name = name;
this.price = price;
this.count = count;
this.volume = volume;
}
@Override
public void List() {
// TODO Auto-generated method stub
System.out.println(this.num+" "+this.name+" "+this.price+"元/天"+" "+"载人:"+this.count+"人 载货:"+this.volume+"吨");
}
}
输出:
欢迎使用咔咔租车:
您是否要租车:1是 0否
1
您可租车的类型及其价目表:
序号 汽车名称 租金 容量
1 奥迪A4 500.0元/天 载人:4人
2 马自达6 400.0元/天 载人:4人
3 皮卡雪6 450.0元/天 载人:4人 载货:2吨
4 金龙 800.0元/天 载人:20人
5 松花江 400.0元/天 载货:4吨
6 依维柯 1000.0元/天 载货:20吨
请输入需要租车的数量:
2
请输入第1辆车的序号:
1
请输入第2辆车的序号:
2
请输入租车天数:
3
您的账单:
=====可载人的车有=====
奥迪A4
马自达6
共载人:8人
=====可载货的车有=====
共载货:0吨
------------
租车总价格为:2700.0元
相关文章
- 暂无相关文章
用户点评