资源描述
1 Object类
Object类是所有类的父类,位于java.lang包中
数组也是Object类的子类
Object类的常用方法
- toString();
- equals();
- hashCode();
- ……
Object类在java.lang包下,是所有类的根。任何类的对象,都可以调用Object类中的方法,包括数组对象。
例:
public class Example{
public void f(Object obj){
}
}
public class Test{
public static void main(){
Example exam=new Example();
int[] array=new int[4];
……//任何数组
exam.f(array);
}
}
Object和Object[]之间的区别
- 方法中的形参是Object类型时,任何类型的参数都可以传进去执行。
- 方法中形参是Object[]类型时,只有对象数组可以传入执行。
例:
public static void arrayTest(Object[] obj){
}
public static void main(){
int[] array=new int[4];
arrayTest(array)//错误出现
}
2 Object类中的常用方法
toString方法;
toString方法可以将任何一个对象转换成
字符串返回,返回值的生成算法为:getClass().getName() + '@' + Integer.toHexString(hashCode())。
equals方法;
Object类中的equals方法,用来比较两个引用的虚地址。当且仅当两个引用在物理上是同一个对象时,返回值为true,否则将返回false。
任何类可以根据实际需要,覆盖toString及equals方法,实现自定义的逻辑。
l 打印对象时直接调用类的toString方法
public static void main(){
Student stu1=new Student();
stu1.setName("张三");
stu1.setAge(23);
System.out.println(stu1);
System.out.println(stu1);
}
打印: Student@152b6651;
l 类本身重写toString方法
重写Student类的toString方法后
public static void main(){
Student stu1=new Student();
stu1.setName("张三");
stu1.setAge(23);
System.out.println(stu1);
}
打印: Student: name=张三,age=23
public class Student {
private String name = "123";// 学生姓名
private int age;// 年龄
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//重写toString方法
}
public String toString(){
return”Student:”+“name=”+name+”,age=”+age;
}
equals方法和“==”
· equals方法
比较对象的虚地址,但是可以在类中被重写。
如:String类重写了,两个相同值的String对象相比较为 true;
String str=new String(“123”);
String str1=new String(“123”);
System.out.println(str.equals(str1));à打印为true.
l “==”
比较的是内存中的虚地址
String str=new String(“123”);
String str1=new String(“123”);
System.out.println(str==str1);à打印为false
hashCode方法
hashCode方法
– 获取对象的哈希码值,为16进制
equals方法与hashCode方法关系
– 如果两个对象使用equals比较返回true,那么它们的hashCode值一定要相同
– 如果两个对象equals比较返回false,那么它们的hashCode值不一定不同
– 覆盖equals,往往需要覆盖hashCode,可以使用Eclipse自动生成,保证equals返回true,则hashCode相同;equals返回false,则hashCode不同
– 在Set集合部分有实际应用
写一个类Course,覆盖Object类中的toString方法,equals,hashCode方法,并写测试代码测试。
package com.chinasofti.ch13;
public class Course {
private String title;
private double price;
public Course(String title, double price) {
super();
this.title = title;
this.price = price;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Course [title=" + title + ", price=" + price + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(price);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((title == null) ? 0 : title.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Course other = (Course) obj;
if (Double.doubleToLongBits(price) != Double
.doubleToLongBits(other.price))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
// public boolean equals(Object o){
// boolean flag=false;
// Course c=(Course)o;
// if(title.equals(c.title)&&price==c.price){
// flag=true;
// }
// return flag;
// }
// public String toString(){
// return "Title: "+title+" Price:"+price;
// }
}
3 接口的基本语法
Java语言中,类与类的继承只能是单继承。
试想一下,如果一个类中的所有方法都是抽象方法,子类继承后,需要重写所有方法,但是因为单继承,就不能去继承其他有实际方法的父类了。
为了解决这个弊端,Java语言中把一种特殊的抽象类定义成一个新的概念,接口,即interface
接口的本质就是一个类,不过是一个纯的抽象类,就是没有变量,没有具体方法的抽象类。
Java接口是一系列方法的声明,是一些抽象的集合
=一个接口只有抽象方法没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
简单地说,接口就是特殊的抽象类,即所有方法都是抽象方法的抽象类就是Java中的接口(interface)
接口的基本格式
[修饰符] interface 接口名 [extends 父接口名列表]{
[public] [static] [final] 常量;
[public] [abstract] 方法;
}
修饰符:可选,用于指定接口的访问权限,可选值为public。即使省略,也依然是public。
接口名:必选参数,用于指定接口的名称,接口名必须是合法的Java标识符。一般情况下,要求首字母大写。
extends 父接口名列表:可选参数,用于指定要定义的接口继承于哪个父接口。当使用extends关键字时,父接口名为必选参数。父接口可以存在多个,用逗号隔开。
方法:接口中的方法只有定义而没有被实现。
接口的特点
接口是一种特殊的抽象类
接口中没有变量,只能有public static final修饰的静态常量。三个修饰符可以省略。
接口中所有方法都是抽象方法,且默认就是public权限。
public interface Flyer {
public static final int TYPE=1;
public abstract void fly();
public abstract void land();
public abstract void takeoff();
}
类实现接口的特点
类实现接口,本质上与类继承类相似,区别在于“类最多只能继承一个类,即单继承,而一个类却可以同时实现多个接口”,多个接口用逗号隔开即可。实现类需要覆盖所有接口中的所有抽象方法,否则该类也必须声明为抽象类。
接口是抽象的,接口中没有任何具体方法和变量,所以接口不能进行实例化。接口定义的是多个类都要实现的操作,即“what to do”。类可以实现接口,从而覆盖接口中的方法,实现“how to do”。
实现接口的基本格式
[修饰符] class <类名> [extends 父类名] [implements 接口列表]{
}
修饰符:可选参数,用于指定类的访问权限,可选值为public、abstract和final。
类名:必选参数,用于指定类的名称,类名必须是合法的Java标识符。一般情况下,要求首字母大写。
extends 父类名:可选参数,用于指定要定义的类继承于哪个父类。当使用extends关键字时,父类名为必选参数。
implements 接口列表:可选参数,用于指定该类实现的是哪些接口。当使用implements关键字时,接口列表为必选参数。当接口列表中存在多个接口名时,各个接口名之间使用逗号分隔。
接口继承接口
有些时候,定义了一个接口后,需要对该接口进一步细化,再定义它的子接口。
也就是接口和接口之间也可以继承,使用extends实现。区别是,接口和接口之间继承是一对多继承。
Java接口继承接口的原则
Java接口可以继承多个接口
接口继承接口依然使用关键字extends,不要错用成implements
Java接口继承接口的形式
Interface3 extends Interface0, Interface1, interface……
实现多重继承
由于Java类要求单继承,如果没有接口的概念,子类一旦继承那些“纯粹”的抽象类,将不能继承其他类。所以Java语言将“纯粹”的抽象类定义为一种新的类型,即“接口”。类可以同时继承类以及实现接口,也就是说extends和implements关键字可以同时使用。而且一个类可以同时实现多个接口,从而实现了对于“纯粹”的抽象类的多重继承,解决了类与类单继承的局限性。
接口继承与类继承对比:Java类的继承是单一继承,Java接口的继承是多重继承。
接口可实现多继承原因分析
不允许类多重继承的主要原因是,如果A同时继承B和C,而B和C同时有一个D方法,A无法确定该继承那一个。
接口全都是抽象方法继承谁都可以,所以接口可继承多个接口
接口与抽象类区别
对比图表
abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface.
在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是 static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。
实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
接口中的方法默认都是 public,abstract 类型的。
接口的作用
接口是设计层面的概念,往往由设计师设计,将定义与实现分离
程序员实现接口,实现具体方法
常见的类设计结构
面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思想体系,属于其一部分。
或者说,它是面向对象编程体系中的思想精髓之一。
面向接口编程的意思是指在面向对象的系统中所有的类或者模块之间的交互是由接口完成的。
Comparable接口
Comparable接口中定义了比较方法,compareTo,返回值为int(忽略泛型,后续学习)
当int值为正数,表示大于;为负数,表示小于;为0,表示等于
API中很多类实现了该接口,很多方法借助该接口
通过使用Arrays.sort(Object[])方法,理解该接口的作用,进一步理解接口的作用
定义Course类,包含名字和价格属性。创建数组,存储多个Course对象。分别使用Arrays类中的sort(Object)方法以及sort(T[],Comparator)方法对数组中元素进行排序。
package com.chinasofit.ch14;
public class Course implements Comparable<Course>{
private String title;
private double price;
public Course(String title, double price) {
super();
this.title = title;
this.price = price;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Course [title=" + title + ", price=" + price + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(price);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((title == null) ? 0 : title.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Course other = (Course) obj;
if (Double.doubleToLongBits(price) != Double
.doubleToLongBits(other.price))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
@Override
public int compareTo(Course o) {
// TODO Auto-generated method stub
if(price>o.price){
return -1;
}else if(price<o.price){
return 1;
}else{
return 0;
}
}
// public boolean equals(Object o){
// boolean flag=false;
// Course c=(Course)o;
// if(title.equals(c.title)&&price==c.price){
// flag=true;
// }
// return flag;
// }
// public String toString(){
// return "Title: "+title+" Price:"+price;
// }
}
package com.chinasofit.ch14;
import java.util.Arrays;
public class TestSort {
public static void main(String[] args){
Course[] courses=new Course[]{new Course("Java",2000),new Course("C",1200),new Course("DB",800)};
// 要求数组的元素必须实现Comparable接口
Arrays.sort(courses);
for(Course c:courses){
System.out.println(c);
}
}
}
展开阅读全文