一、Object类是所有类的基类。
Object类的几个常见方法:
toString():当输出一个对象,系统默认调用其toString方法。通常我们需要重写toString方法。
equals(Object obj) :判断其他某个对象是否与此对象“相等”。 当且仅当两个引用指向同一个对象时,才返回true;String、Data等类重写了该方法,对象值相等时,返回true;注:s1==s2当且仅当s1和s2指向同一块内存单元时,才相等。
String类重写了Object类的hashCode方法 ,使得值相同的hash码相同。
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
示例
public class HashCodeDemo {
public static void main(String[] args) {
StringBuffer sb1 = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
String str3 = new String("abc");
String str4 = new String("abc");
System.out.println(sb1.hashCode());
System.out.println(sb2.hashCode());
System.out.println(str3.hashCode());
System.out.println(str4.hashCode());
}
}
输出结果
23979164
29094346
96354
96354
StringBuffer类没有重写hashCode方法,直接继承了Object类的hashCode方法。String类重写了该方法,使得相同的内容hashCode也相同。注:重写equals方法必须重写hashCode方法。
public class EqualsTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Cat c1 = new Cat(1,2,3);
Cat c2 = new Cat(1,2,3);
System.out.println(c1==c2);
System.out.println(c1.equals(c2));
}
}
class Cat{
int color;
int height;
int weight;
public Cat(int color,int height,int weight){
this.color = color;
this.height = height;
this.weight = weight;
}
}
输出结果:
false
false
默认情况下,s1==s2和s1.equals(s2)都是判定s1和s2是否指向同一个引用。所以返回false。
重写equals方法
public class EqualsTest {
public static void main(String[] args) {
Cat c1 = new Cat(1,2,3);
Cat c2 = new Cat(1,2,3);
System.out.println(c1==c2);
System.out.println(c1.equals(c2));
}
}
class Cat{
int color;
int height;
int weight;
public Cat(int color,int height,int weight){
this.color = color;
this.height = height;
this.weight = weight;
}
public boolean equals(Object obj){
if (obj == null) {
return false;
} else if (obj instanceof Cat) {
Cat c = (Cat) obj;
if (color == c.color && height == c.height && weight == c.weight) {
return true;
}
}
return false;
}
}
返回结果
false
true
二、对象转型
假若猫是动物的子类。动物有eat()方法。
则:Animal a = new Cat();//此时就是类型的提升,就是向上转型。
a.eat();
Cat c = (Cat) a;//强制将父类的引用转成子类类型。向下转型。
c.catchMouse();
class Animal{
public String name;
Animal(String name){
this.name = name;
}
}
class Cat extends Animal{
public String eyesColor;
Cat(String n,String c){
super(n);
eyesColor = c;
}
}
class Dog extends Animal{
public String furColor ;
Dog(String n,String c){
super(n);
furColor = c;
}
}
public class TestDemo {
public static void main(String[] args) {
Animal a = new Animal("name");
Cat c = new Cat("catName","blue");
Dog d = new Dog("dogName","black");
System.out.println(a instanceof Animal);
System.out.println(c instanceof Animal);
System.out.println(d instanceof Animal);
System.out.println(a instanceof Cat);
a = new Dog("bigyellow","yellow");
System.out.println(a.name);
System.out.println(a instanceof Animal);
System.out.println(a instanceof Dog);
//强制类型转化
Dog d1 = (Dog)a;
System.out.println(d1.furColor);
}
}
输出结果
true
true
true
false
bigyellow
true
true
yellow
再来看一个对象转型的例子
class Animal{
public String name;
Animal(String name){
this.name = name;
}
}
class Cat extends Animal{
public String eyesColor;
Cat(String n,String c){
super(n);
eyesColor = c;
}
}
class Dog extends Animal{
public String furColor ;
Dog(String n,String c){
super(n);
furColor = c;
}
}
public class TestDemo {
public static void main(String[] args) {
TestDemo test = new TestDemo();
Animal a = new Animal("name");
Cat c = new Cat("catName","blue");
Dog d = new Dog("dogName","black");
test.f(a);
test.f(c);
test.f(d);
}
public void f(Animal a){
System.out.println("name:"+a.name);
if(a instanceof Cat){
Cat c = (Cat)a;
System.out.println(c.eyesColor);
}else if(a instanceof Dog){
Dog d = (Dog)a;
System.out.println(d.furColor);
}
}
}
输出结果
name:name
name:catName
blue
name:dogName
black
三、动态绑定和多态
什么是动态绑定:根据实际的传进来的对象来调用相应的方法。
多态的存在一般包含继承、方法的重写、父类引用指向子类对象。
示例分析
class Animal{
private String name;
Animal(String name){
this.name = name ;
}
public void enjoy(){
System.out.println("叫声...");
}
}
class Cat extends Animal{
private String eyesColor;
Cat(String n,String c){
super(n);
eyesColor = c;
}
//重写enjoy方法
public void enjoy(){
System.out.println("猫叫声...");
}
}
class Dog extends Animal{
private String furColor;
Dog(String n,String c){
super(n);
furColor = c;
}
//重写enjoy方法
public void enjoy(){
System.out.println("狗叫声...");
}
}
class Lady{
private String name;
private Animal pet;
Lady(String n,Animal pet){
this.name = name;
this.pet = pet;
}
public void myPetEnjoy(){
pet.enjoy();
}
}
public class TestDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Animal a = new Animal("animalName");
Cat c = new Cat("catName","blue");
Dog d = new Dog("dogName","black");
Lady l = new Lady("l",a);
Lady l1 = new Lady("l1",c);
Lady l2 = new Lady("l2",d);
l.myPetEnjoy();
l1.myPetEnjoy();
l2.myPetEnjoy();
}
}
输出结果
叫声...
猫叫声...
狗叫声...
四、抽象类
1、用abstract关键字修饰的类为抽象类,用abstract关键字修饰的方法称为抽象方法。
2、含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。
3、抽象类不能实例化。
4、抽象方法只需声明,不需实现。
改写一下上面Animal的定义,将Animal声明为抽象类。
abstract class Animal{
private String name;
Animal(String name){
this.name = name ;
}
abstract public void enjoy();//抽象方法只需声明,不需实现。
}
五、final关键字修饰
1.final 修饰类,则该类不可以被继承;
2.final修饰方法,则该方法不可以被重载;
3.final修饰属性,则该属性不能进行隐式初始化,必须先付初值或者在构造方法中赋值;
六、接口 interface
java只支持单继承,利用接口来支持多个继承关系,一个类可以实现多个接口。
1、接口是抽象方法和常量值的定义的集合
2、从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义;而没有变量和方法的实现。
3、接口定义举例
interface Runner{
public static final int id= 1;
public void start();
public void run();
public void stop();
}
接口特性
1、一个类可以实现多个接口
2、接口中声明的属性默认为public static final,也只能是public static final
3、接口中只能定义抽象方法,这些方法默认为public的,也只能是public;
4、接口可以继承其他接口,添加新的属性和方法
5、多个无关的类可以实现同一个接口
6、一个类可以实现多个接口
7、与继承关系类似,接口和实现类之间存在多态关系