Java PTA(6)——继承与多态

1.判断题

1.1 如果一个类的声明中没有使用extends关键字,这个类被系统默认为是继承Object类。(T)

1.2 构造方法可以调用本类中重载的构造方法和它的父类的构造方法。(T)

1.3 Java只支持单继承,也就是说子类只能有一个直接父类 。(T)

1.4 Object类是所有其它类的直接或间接父类。(T)

1.5 设类B是类C的父类,语句B x1=new C( ); 是正确的。(T)

2.单选题

2.1 类Teacher和Student是类Person的子类,下面的代码中最后一句语句的运行结果是( ).

Person p;
Teacher t;
Student s;
//p,t and s are all non-null.
if(t instanceof Person)  {s=(Student)t;}

A.编译时正确,但运行时错误

B.将构造一个Student对象

C.表达式是错误的

D.表达式是合法的

2.2 以下程序运行结果是

public class Test extends Father{
    private String name="test";
    public static void main(String[] args){
        Test test = new Test();
        System.out.println(test.getName());
    }
}
class Father{
    private String name="father";
    public String getName() {
        return name;
    }
}

A.father

B.编译出错

C.test

D.运行出错,无输出

2.3 下列选项中关于java中super关键字的说法错误的是

A.super关键字是在子类对象内部指代其父类对象的引用

B.super关键字不仅可以指代子类的直接父类,还可以指代父类的父类

C.子类可以通过super关键字调用父类的方法

D.子类可以通过super关键字调用父类的属性

2.4 下面描述中正确的是?

A.创建子类的对象时,先调用子类自己的构造方法,然后调用父类的构造方法。

B.子类无法继承父类的构造方法。

C.子类无条件地继承父类不含参数的构造方法。*

D.子类必须在自己的构造方法中用super关键字显式地调用父类的构造方法。

2.5 关于关键字instanceof的说法不正确的是:( )。

A.它不能作为标识符名称出现

B.它用来表示某变量所指向的对象是否是另一种类型的实例

C.

Scanner sc=new Scanner(System.in);
boolean b=sc instanceof String;
//这种用法是正确的

D.

Scanner sc=new Scanner(System.in);
boolean b=sc instanceof Object;
//这种用法是正确的

instanceof左边显式声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误 

2.6 有如下程序代码,程序编译(执行)的结果为:

class A {
 int v1 = 10;
 int v2 = 10;
 public A() {
 }
 public void m1() {
  System.out.println("A m1");
 }
 public void m2() {
  System.out.println("A m2");
 }
}

class B extends A {
 int v2 = 20;
 int v3 = 20;
 public B() {
 }
 public void m2() {
  System.out.println("B m2");
 }
 public void m3() {
  System.out.println("B m3");
 }
}
public class Main {
 public static void main(String[] args) {
  B b = new B();
  b.m1();
  b.m2();
  b.m3();
  System.out.println(b.v1);
  System.out.println(b.v2);
  System.out.println(b.v3);
 }
}

A.

B m1
B m2
B m3
20
20
20

B.

A m1
B m2
B m3
10
20
20

C.

A m1
B m2
B m3
20
20
20

D.

A m1
B m2
B m3
20
10
20

2.7 以下关于继承的叙述正确的是( )。

A.在Java中类只允许单一继承

B.在Java中,一个类只能实现一个接口

C.在Java中,一个类不能同时继承一个类和实现一个接口

D.在Java中,接口也具有单继承性

2.8 在某个类中存在一个方法:void getSort(int x),以下能作为这个方法的重载的声明的是( )

A.public get (float x)

B.int getSort(int y)

C.double getSort(int x,. int y)

D.void get(int x, int y)

2.9 下面程序的输出结果为:( )。

class A {
 double f(double x, double y) {
  return x * y;
 }
}

class B extends A {
 double f(double x, double y) {
  return x + y;
 }
}

public class Test {
 public static void main(String args[]) {
  A obj = new B();
  System.out.println(obj.f(4, 6));
 }
}

A.10.0

B.24.0

C.2.0

D.11.0

2.10 在下面的代码中,若要在子child类中对父类的addvalue方法进行重写,下面对于child类中的addvalue方法的声明哪个是正确的:( )。

class father {
 public int addvalue(int a, int b) {
  int s = a + b;
  return s;
 }
}

class child extends father {

}

A.public int addvalue(int i,int j)

B.void addvalue(int a,int b)

C.void addvalue(double i)

D.int addvalue(int a)

2.11 下列关于抽象类的说法哪一个是错误的。

A.含抽象方法的类为抽象类

B.抽象类能创建(new)实例

C.子类有未实现父类的抽象方法时仍为抽象类

D.子类实现所有抽象方法时不再是抽象类

2.12 下面类的定义,哪个是合法的抽象类定义。

A.class A { abstract void unfinished() { } }

B.class A { abstract void unfinished(); }

C.abstract class A { abstract void unfinished(); }

D.public class abstract A { abstract void unfinished(); }

2.13 以下对接口描述错误的有

A.接口没有提供构造方法

B.接口中的方法默认使用public、abstract修饰

C.接口中的属性默认使用public、static、final修饰

D.接口不允许多继承

2.14 给定以下代码,请问下列选项中哪个是正确的?

public interface Top{
  void twiddle(String s);
}

A.

public abstract class Sub implements Top{
  public abstract void twiddle(String s){ }
}

B.

public class Sub implements Top{
  public void twiddle(Integer i){ }
}

C.

public class Sub implements Top{
  void twiddle(String s){ }
}

D.

public class Sub implements Top{
  public void twiddle(String s){ }
  public void twiddle(Integer i){ }
}

2.15 多态的表现形式有

A.重写

B.继承

C.抽象

D.封装

2.16 已知类的继承关系如下:

class Employee;

class Manager extends Employee;

class Director extends Employee;
则以下语句哪个能通过编译? ( )。

A.Employee e = new Manager();

B.Director d = new Manager();

C.Director d = new Employee();

D.Manager m = new Director();

3.程序填空题

3.1实现接口

本题目要求两个类Sum和Pro分别实现接口OneToN。Sum类求整数1至n的和,Pro求整数1至n的积。

interface OneToN{

        int disp(int n);

}

class Sum implements OneToN        //2 分{ // 继承接口

        public int disp(int n){ // 实现接口中的disp方法

                int s = 0,i;

                for(i = 1;i <= n;i ++)

                        s += i; return s;

             }

}

class Pro  implements OneToN        //2 分{ // 继承接口

        public int disp(int n){ // 实现接口中的disp方法

                int m = 1,i;

                for(i = 1;i <= n;i ++)    m *= i;     //2 分

                return m;

        }

}

public class Main{

        public static void main(String args[]){

                int n = 10;

                Sum s = new Sum();             //2 分

                Pro p = new Pro();              //2 分

                System.out.println("sum of1 to n = " + s.disp(n));

                System.out.println("pro of 1to n = " + p.disp(n));

        }

}

4.函数题

4.1  jmu-Java-03面向对象基础-覆盖与equals

Person类,Company类,Employee类。

其中Employee类继承自Person类,属性为:

private Company company;
private double salary;

现在要求覆盖Employee类的equals方法,判定两个Employee对象是否相等,请见如下判断方法:

  1. 其继承自父类Person的属性值都相等,其company属性对象equals返回true,且其salary也相等。

  2. salary是double型,比较时,使用DecimalFormat df = new DecimalFormat("#.##");使salary保留两位小数,然后再进行比较。

注意:要考虑company为null的情况。

函数接口定义:

public boolean equals(Object obj)

输入样例:

此题无输入样例。main方法中已经包含多种不同的测试情况,下面的输出就是这多种测试情况的输出。

 

输出样例:

false
true
false
true
false
true
false

代码: 

public boolean equals(Object obj) {
        //直接比较引用的地址码是否相同
    if (this == obj) return true;
        //判断传入的参数是否为null
    if (obj == null) return false;
        //判断父类的属性是否相同
    if (!super.equals(obj)) return false;
        //浮点数的比较和company为null的情况的辨析
    DecimalFormat df = new DecimalFormat("#.##");
    Employee other = (Employee) obj;
    if (company == null && other.company == null) 
        return df.format(salary).equals(df.format(other.salary));
    else if (company == null || other.company == null) return false;
    return company.equals(other.company)
            && df.format(salary).equals(df.format(other.salary));
}

4.2 从抽象类shape类扩展出一个圆形类Circle

请从下列的抽象类shape类扩展出一个圆形类Circle,这个类圆形的半径radius作为私有成员,类中应包含初始化半径的构造方法。

public abstract class shape {// 抽象类

public abstract double getArea();// 求面积

public abstract double getPerimeter(); // 求周长

}

主类从键盘输入圆形的半径值,创建一个圆形对象,然后输出圆形的面积和周长。保留4位小数。

圆形类名Circle

裁判测试程序样例:

import java.util.Scanner;
import java.text.DecimalFormat;
 
abstract class shape {// 抽象类
     /* 抽象方法 求面积 */
    public abstract double getArea( );
 
    /* 抽象方法 求周长 */
    public abstract double getPerimeter( );
}

/* 你提交的代码将被嵌入到这里 */

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        DecimalFormat d = new DecimalFormat("#.####");// 保留4位小数
         double r = input.nextDouble( ); 
        shape c = new  Circle(r);
 
        System.out.println(d.format(c.getArea()));
        System.out.println(d.format(c.getPerimeter()));
        input.close();
    } 
}

输入样例:

3.1415926

输出样例:

31.0063
19.7392

代码:

class Circle extends shape {
    private double radius;
    public Circle(double r) {
        radius=r;
    }
    public double getArea() {
        return Math.PI*radius*radius;
    }    
    public double getPerimeter() {
        return Math.PI*2*radius;
    }
}

5.编程题

5.1  jmu-Java-03面向对象-06-继承覆盖综合练习-Person、Student、Employee、Company

定义Person抽象类,Student类、Company类,Employee类。

Person类的属性String name, int age, boolean gender
Person类的方法:

public Person(String name, int age, boolean gender);
public String toString();         //返回"name-age-gender"格式的字符串
public boolean equals(Object obj);//比较name、age、gender,都相同返回true,否则返回false

Student类继承自Person,属性:String stuNo, String clazz
Student类的方法:

//建议使用super复用Person类的相关有参构造函数
public Student(String name, int age, boolean gender, String stuNo, String clazz);
public String toString();         //返回 “Student:person的toString-stuNo-clazz”格式的字符串
public boolean equals(Object obj);//首先调用父类的equals方法,如果返回true,则继续比较stuNo与clazz。

Company类属性:String name
Company类方法:

public Company(String name);
public String toString();         //直接返回name
public boolean equals(Object obj);//name相同返回true

Employee类继承自Person,属性:Company company, double salary
Employee类方法:

//建议使用super复用Person类的相关有参构造函数
public Employee(String name, int age, boolean gender, double salary, Company company);
public String toString();         //返回"Employee:person的toString-company-salary"格式的字符串
public boolean equals(Object obj);//首先调用父类的equals方法,如果返回true。再比较company与salary。
//比较salary属性时,使用DecimalFormat df = new DecimalFormat("#.#");保留1位小数

编写equals方法重要说明:

  1. 对Employee的company属性的比较。要考虑传入为null的情况。如果company不为null且传入为null,返回false
  2. 对所有String字符类型比较时,也要考虑null情况。

提示

  1. 排序可使用Collections.sort
  2. equals方法要考虑周全

main方法说明

  1. 创建若干Student对象、Employee对象。
    输入s,然后依次输入name age gender stuNo clazz创建Student对象
    输入e,然后依次输入name age gender salary company创建Employee对象
    然后将创建好的对象放入List<Person> personList。输入其他字符,则结束创建。

创建说明: 对于String类型,如果为null则不创建对象,而赋值为null。对于company属性,如果为null则赋值为null,否则创建相应的Company对象。

  1. 对personList中的元素实现先按照姓名升序排序,姓名相同再按照年龄升序排序。提示:可使用Comparable<Person>Comparator<Person>

  2. 接受输入,如果输入为exitreturn退出程序,否则继续下面步骤。

  3. 将personList中的元素按照类型分别放到stuList与empList。注意:不要将两个内容相同的对象放入列表(是否相同是根据equals返回结果进行判定)。

  4. 输出字符串stuList,然后输出stuList中的每个对象。

  5. 输出字符串empList,然后输出empList中的每个对象。

1-3为一个测试点
4-6为一个测试点

输入样例:

s zhang 23 false 001 net15
e wang 18 true 3000.51 IBM
s zhang 23 false 001 net15
e bo 25 true 5000.51 IBM
e bo 25 true 5000.52 IBM
e bo 18 true 5000.54 IBM
e tan 25 true 5000.56 IBM
e tan 25 true 5000.51 IBM
s wang 17 false 002 null
s wang 17 false 002 null
e hua 16 false 1000 null
s wang 17 false 002 net16
e hua 16 false 1000 null
e hua 18 false 1234 MicroSoft
!
continue

输出样例:

Employee:bo-18-true-IBM-5000.54
Employee:bo-25-true-IBM-5000.51
Employee:bo-25-true-IBM-5000.52
Employee:hua-16-false-null-1000.0
Employee:hua-16-false-null-1000.0
Employee:hua-18-false-MicroSoft-1234.0
Employee:tan-25-true-IBM-5000.56
Employee:tan-25-true-IBM-5000.51
Student:wang-17-false-002-null
Student:wang-17-false-002-null
Student:wang-17-false-002-net16
Employee:wang-18-true-IBM-3000.51
Student:zhang-23-false-001-net15
Student:zhang-23-false-001-net15
stuList
Student:wang-17-false-002-null
Student:wang-17-false-002-net16
Student:zhang-23-false-001-net15
empList
Employee:bo-18-true-IBM-5000.54
Employee:bo-25-true-IBM-5000.51
Employee:hua-16-false-null-1000.0
Employee:hua-18-false-MicroSoft-1234.0
Employee:tan-25-true-IBM-5000.56
Employee:tan-25-true-IBM-5000.51
Employee:wang-18-true-IBM-3000.51

代码:

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) throws InterruptedException {
       Scanner sc=new Scanner(System.in);
       List<Person> personList=new ArrayList<Person>();
       String name;
       int age;
       boolean gender;
       String stuNo;
       String clazz;
       String companyName;
       Company company;
       double salary;
       //输入
       while(true) {
    	   String t=sc.next();
    	   if(t.equals("s")) {
    		   name=sc.next();
    		   age=sc.nextInt();
    		   gender=sc.nextBoolean();
    		   stuNo=sc.next();
    		   clazz=sc.next();
    		   if(name==null||stuNo==null||clazz==null) {
    			   continue;
    		   }
    		   personList.add(new Student(name, age, gender, stuNo, clazz));
    		   
	       }else if(t.equals("e")){
	    	   name=sc.next();
    		   age=sc.nextInt();
    		   gender=sc.nextBoolean();
    		   salary=sc.nextDouble();
    		   companyName=sc.next();
    		   company=new Company(companyName);
    		   if(name==null) {
    			   continue;
    		   }
    		   //除了companyName可以为空,其他为空均不能创建对象(应该是这么理解吧)
    		   if(companyName==null) {
    			   companyName="null";   //为空的话要给他赋值为空(删了也能过 可能写了句废话 )
    		   }
	    	   personList.add(new Employee(name, age, gender, company, salary));
	       }else{         //要是遇到感叹号就该结束输入啦(题目上好像没说)
	    	   break;
	       }
	      
       }
        //排序(因为之前的类都建好了,Person类还是抽象类,所以比较器只能用Comparator了)
       Collections.sort(personList, new Name_AgeComparator());
      
       for(int i=0;i<personList.size();i++) {
    	   
    		   System.out.println(personList.get(i).toString()); 
    	  
       }
      //只要不输入return和exit就要分组啦
       String str=sc.next();
       while(true) {
    	   if(str.equals("return")||str.equals("exit")) {
    		   break;
    	   }else {
        	   //分组
               List<Person> stuList=new ArrayList<Person>();
               List<Person> empList=new ArrayList<Person>();
               //判断过程要根据equals 是自己定义的 所以比较工资那有坑,用contains是不行的 所以还是循环比较吧
               boolean flag1=true;
               boolean flag2=true;
               for(int i=0;i<personList.size();i++) {
            	   if(personList.get(i).toString().indexOf("Student")>=0) {
            		   if(stuList.size()==0) {
            			   stuList.add(personList.get(i));
            		   }
            		   for(int j=0;j<stuList.size();j++) {
            			   if(personList.get(i).equals(stuList.get(j))){
            				   flag1=false;
            			   }
            		   }
            		   if(flag1) {
            			   stuList.add(personList.get(i));
            			   
            		   }
            		   flag1=true;
            	   }else {
            		   if(empList.size()==0) {
            			   empList.add(personList.get(i));
            		   }
            		   for(int j=0;j<empList.size();j++) {
            			   if(personList.get(i).equals(empList.get(j))){
            				   flag2=false;
            			   }
            		   }
            		   if(flag2) {
            			   empList.add(personList.get(i));
            		   }
            		   flag2=true;
            	   }
               }
               System.out.println("stuList");
               for(int i=0;i<stuList.size();i++) {
            	   
        		   System.out.println(stuList.get(i).toString()); 
        	  
               }
               System.out.println("empList");
               for(int i=0;i<empList.size();i++) {
            	   
        		   System.out.println(empList.get(i).toString()); 
        	  
               }
               break;
           } 
    	   }

       
       
    }
    //Comparator需要创建一个类,又因为想在main方法里直接调,所以就要用static修饰
    static class Name_AgeComparator implements Comparator<Person>{  //不加这个泛型也可以,但以后要强制转换

		@Override
		public int compare(Person o1, Person o2) {
			 if(o1.name.compareTo(o2.name)==0) {
				if(o1.age==o2.age) {
					return 0;
				}else if(o1.age<o2.age) {
					return -1;
				}else {
					return 1;
				}
			}else {
				//比较字符串的方法(放张图片吧)
				return(o1.name.compareTo(o2.name));
			}
		}
    	
    }
    
    
}
abstract class Person{
	String name;
	int age;
	boolean gender;
	public Person(String name, int age, boolean gender) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	@Override
	public String toString() {
		
		return this.name+'-'+String.valueOf(this.age)+'-'+String.valueOf(this.gender);
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (gender != other.gender)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
}
class Student extends Person{
	String stuNo;
	String clazz;
	public Student(String name, int age, boolean gender, String stuNo, String clazz) {
		super(name,age,gender);
		this.clazz=clazz;
		this.stuNo=stuNo;
	}
	@Override
	public String toString() {
		return"Student:"+ super.toString()+'-'+this.stuNo+'-'+this.clazz;
	}
	@Override
	public boolean equals(Object obj) {
		if (!super.equals(obj))
			return false;
		if (this == obj)
			return true;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (clazz == null) {
			if (other.clazz != null)
				return false;
		} else if (!clazz.equals(other.clazz))
			return false;
		if (stuNo == null) {
			if (other.stuNo != null)
				return false;
		} else if (!stuNo.equals(other.stuNo))
			return false;
		return true;
	}
	
	
}
class Company{
	String name;
	public Company(){
		
	}
	public Company(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return name;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Company other = (Company) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
	
}
class Employee extends Person{
	Company company;
	double salary;
	public Employee(String name, int age, boolean gender, Company company, double salary) {
		super(name, age, gender);
		this.company = company;
		this.salary = salary;
	}
	@Override
	public String toString() {
		return "Employee:"+ super.toString()+'-'+company+'-'+salary;
	}
	@Override
	public boolean equals(Object obj) {
		if (!super.equals(obj))
			return false;
		if (this == obj)
			return true;
		if (getClass() != obj.getClass())
			return false;
		Employee other = (Employee) obj;
		if (company == null) {
			if (other.company != null)
				return false;
		} 
		else if (!company.equals(other.company))
			return false;
		//坑在这啊,要用decimal比较,要学会decimal这种用法
		DecimalFormat df = new DecimalFormat("#.#");
		if (!df.format(salary) .equals( df.format(other.salary)))
			return false;
		return true;
	}
	
	
	
	
}

5.2  jmu-Java-04面向对象进阶--02-接口-Comparator

Arrays.sort可以对所有实现Comparable的对象进行排序。但如果有多种排序需求,如有时候需对name进行降序排序,有时候只需要对年龄进行排序。使用Comparable无法满足这样的需求。可以编写不同的Comparator来满足多样的排序需求。

1.编写PersonSortable2类

属性:private name(String)private age(int)
有参构造函数:参数为name,age
toString方法:返回格式name-age

2 编写Comparator类

  1. 编写NameComparator类,实现对name进行升序排序
  2. 编写AgeComparator类,对age进行升序排序

3.main方法中

  1. 输入n
  2. 输入n行name age,并创建n个对象放入数组
  3. 对数组按照name进行升序排序后输出。
  4. 在3的基础上对数组按照age进行升序排序后输出。
  5. 最后最后两行使用如下代码输出NameComparator与AgeComparator所实现的所有接口。
System.out.println(Arrays.toString(NameComparator.class.getInterfaces()));
System.out.println(Arrays.toString(AgeComparator.class.getInterfaces()));

输入样例:

5
zhang 15
zhang 12
wang 14
Wang 17
li 17


输出样例:

NameComparator:sort
Wang-17
li-17
wang-14
zhang-15
zhang-12
AgeComparator:sort
zhang-12
wang-14
zhang-15
Wang-17
li-17
//最后两行是标识信息

代码:

 
import java.util.*;
 
public class Main{
	public static void main(String[] args) {
		Scanner scan=new Scanner(System.in);
		int n=scan.nextInt();
		PersonSortable2 s[]=new PersonSortable2[n];
		for(int i=0;i<n;i++) {
			String name=scan.next();
			int age=scan.nextInt();
			s[i]=new PersonSortable2(name,age);
		}
		scan.close();
		Arrays.sort(s, new NameComparator());
		System.out.println("NameComparator:sort");
		for(PersonSortable2 i:s) {
			System.out.println(i);
		}
		Arrays.sort(s, new AgeComparator());
		System.out.println("AgeComparator:sort");
		for(PersonSortable2 i:s) {
			System.out.println(i.toString());
		}
		System.out.println(Arrays.toString(NameComparator.class.getInterfaces()));
		System.out.println(Arrays.toString(AgeComparator.class.getInterfaces()));
	}
}
class PersonSortable2{
	public String name;
	public int age;
	public PersonSortable2(String name,int age) {
		this.name=name;
		this.age=age;
	}
	@Override
	public String toString() {
		return name + "-" + age;
	}
	
}
class NameComparator implements Comparator<PersonSortable2>{
 
	@Override
	public int compare(PersonSortable2 o1, PersonSortable2 o2) {
		if(o1.name.compareTo(o2.name)>0)return 1;
		else if(o1.name.compareTo(o2.name)<0)return -1;
		else return o1.name.compareTo(o2.name);
	}
}
class AgeComparator implements Comparator<PersonSortable2>{
 
	@Override
	public int compare(PersonSortable2 o1, PersonSortable2 o2) {
		if(o1.age<o2.age)return -1;
		else return 1;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值