//继承简单表示 public class Son extends Father{ //将特殊的方法放在子类中 } class Father { //我们通常将一般的方法放在父类中,因为父类的方法子类都可以用。 }
this.变量
的方式表示使用的是本类的变量super.方法
,调用父类的方法。public class Son extends Father{ Son(String name, int age) { super(name, age);//如果子类的构造器没有显示的调用父类的构造器,则将默认的调用父类的无参构造。 } } class Father { String name; int age; Father(String name,int age) { this.name = name; this.age = age; } } //若父类中没有无参构造,而子类构造器中又没有调用父类的其它构造器,则Java编译器会报错。
对于继承简言之就是:父类有的子类都有,父类没有的子类也可以有
public void instanceOf(Animal T) { if(T instanceof Dog) { //我们传进来的dog就是此时的T,通过instanceof检测它是否属于Dog或者Animal,可以判断对象的类型。 //此时的语句应该是这样的 Animal T = new Dog(); 而我们应该将T向下转型 t = (Dog) T; System.out.println("yes"); } }
Animal dog = new Dog(); Animal cat = new Cat(); cat.instanceOf(dog);//程序将输出"yes"
public class Animal { public void play() { System.out.println("玩"); } public void eat() { System.out.println("吃"); } }
public class Cat extends Animal{ public void eat() { System.out.println("猫吃饭,亲密度+8"); } public void play() { System.out.println("撸猫,体力值-9"); } }
public class Test { public static void main(String[] args) { Animal cat = new Cat();//此时cat被看成是Animal的对象,但实际上本质是Cat的。 //在编译阶段我们看左边,它是Animal骗过编译器,但真正运行的时候它会看右边。 cat.eat(); cat.play(); //最终输出“猫吃饭,亲密度+8”和“撸猫,体力值-9”。这就是多态的应用 //看右边,就是先去寻找Cat中是否有重写的父类方法,如果有则调用自己的。如果没有则用父类的。 //可以记为:先调子类,再调父类。 } }
Animal cat = new Cat();这也是向上转型,将Cat类的转成了Animal
Java规范要求equals方法具有下面的特性:
1.自反性:对于任何非空引用x,x.equals(x)应该返回true。
2.对称性:对于任何引用x和y,当且仅当y.equals(x)返回true时,x.equals(y)返回true。
3.传递性:对于任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,则x.equals(z)也应该为true。
4.一致性:如果x和y引用的对象没有发生变化,反复调用x.equals(y)应该返回同样的结果。
5.对于任意非空引用x,x.equals(null)应该返回false。
instanceof
实现重写equals
方法getClass
实现重写equals
方法class Son extends Father{ public static void main(String[] args) { Son son = new Son(); Father father = new Father(); Father sss = new Son(); System.out.println(father.equals(son)); } } class Father{ public boolean equals(Object obj) { if(this == obj) return true;//判断是否同一个对象 //如果两个类不是同一个类 // if(obj == null || obj.getClass() != this.getClass()) { // return false; // } //传进来的对象不属于这个类或者它的父类,返回false System.out.println(obj.getClass()); if(obj == null || !(obj instanceof Father)) {//左边是子类或者本类的对象 return false; } Father obj1 = (Father) obj;//强转然后判断 return true; } }
- 这里instanceof的缺点就是,父类调用比较子类为true,子类调用比较父类为false,所以我们可以尽量调用父类的equals来避免这个问题。
- 同时也可以使用getClass进行判断,是否为同一个类对象。
int hash = 0; for(int i = 0; i < length(); i++) { hash = 31*hash + charAt(i); }
- 对于字符串的散列码,是看字符串的内容而定的。意味着两个字符串内容相同,则他们的散列码也相同。
@Override public String toString() { return getClass().getName() +"{" + "tili=" + tili + ", qimi=" + qimi + '}'; }
System.out.println(x.toString());
System.out.println(x);这样会默认调用toString()方法,可以简略不写
但是在有时候我们用toString方法是会出现输出java.io.PrintStream@2f6684和[I@1a46e30的情况
1.这是因为Objcet类定义了toString方法,可以打印对象的类名和散列码,所以需要我们对toString方法进行重写
2.数组也继承了Objcet类的toString,如果我们使用时不重写toString,则会出现[I@1a46e30
,补救办法就时使用Arrays.toString()
3.若是二维数组,则可以使用Arrays.deepToString()方法
4.强烈建议在每一个类中都重写toString方法。
int x = Integer.parseInt(s);
String s = String.ValueOf(x);
System.out.println(sum(1,2,3,4,5)); public static int sum(int... a) { int total = 0; for(int i:a) { total += i; } return total; }