面向对象3大特性:封装、继承、多态——继承(继承方法的重写和初始化顺序、final & super关键字、Object类)
继承和方法的重写
继承的语法规则:
java中的继承是单继承,一个类只有一个父类
继承的好处:
子类拥有父类的所有属性和方法(属性和方法的修饰符不能是private,不然是无效的)
实现代码复用
class 子类 extends 父类
例:class Dog extends Animal{
} //Dog 继承了Animal类
什么是方法的重写?
如果子类对继承父类的方法不满意,是可以重写父类继承的方法的,当调用时会优先调用子类的方法。
语法规则:
返回值类型 、方法名、参数类型及个数,都要与父类继承的方法相同,才叫方法的重写。
继承的初始化顺序
1、先初始化父类再初始化子类
2、先初始化属性再初始化构造方法
public class Animal { public int age=10; public String name; public void eat(){ System.out.println("动物具有吃东西的能力"); } public Animal(){ System.out.println("Animal类执行了"); age=20; } } public class Dog extends Animal { public void eat(){ System.out.println("狗狗具有吃东西的能力"); } public Dog(){ System.out.println("Dog类执行了"); } } public class Initial { public static void main(String[] args) { // TODO Auto-generated method stub Dog dog=new Dog(); dog.eat(); System.out.println(dog.age); } }
final关键字
使用final关键字做标识有“最终的”含义
final可以修饰类、方法、属性、变量
final修饰类,则该类不允许被继承
final修饰方法,则该方法不允许被覆盖(重写)
final修饰属性,则该类的属性不会进行隐式的初始化(类的初始化属性必须有值),或者在构造方法中赋值(但只能选其一)
final修饰变量,则该变量的值只能赋一次值,即常量
super关键字
在对象的内部使用,可以代表父类对象
1、访问父类的属性 super.age
2、访问父类的方法 super.eat()
子类的构造过程中必须调用其父类的构造方法 super();
如果子类的构造方法中没有显式调用父类的构造方法,则系统默认调用父类无参的构造方法
如果显式的调用构造方法,必须在子类构造方法的第1行
如果子类构造方法中既没有显示调用父类的构造方法,而父类有没有无参的构造方法,则编译出错。
public class Animal { public int age=10; public String name; public void eat(){ System.out.println("动物具有吃东西的能力"); } public Animal(int age){ this.age=age; } } public class Dog extends Animal { public static int age=20; public void eat(){ System.out.println("狗狗具有吃东西的能力"); } public Dog(){ //调用父类有参构造方法 super(age);//入参的age属性必须加static System.out.println("Dog类执行了"); } public void method(){ System.out.println(super.age);//调用的是父类的属性 super.eat();//调用的是父类的方法 } }
Object类
Object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object类。Object类中的方法,适用于所有子类。
object类中的方法:
1、toString()
在object类里面定义toString()方法的时候返回对象的哈希码(对象地址字符串)
可以通过重写toString()方法表示出对象的属性
菜单栏:source→generate toString 自动生成重写的toString()方法
@Override public String toString() { return "Dog [age=" + age + ", name=" + name + "]"; }
2、equals()
比较的是 对象的引用是否指向同一块内存地址Dog dog=new Dog()
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("两个对象是不同的"); } } >>> 两个对象是不同的
一般情况下比较两个对象时比较它们的值是否一致,所以要进行重写!
菜单栏:source→generate hashCode() and equals()
自动生成重写的hashCode()和equals()方法
注意:
getClass()方法是获取类对象,类对象和类的对象(创建的对象就是类的对象)是不一样的。类对象获取的是类的属性,类的对象关注的是类的属性值!!
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; //判断类对象是否相等 if (getClass() != obj.getClass()) return false; Dog other = (Dog) obj;//强制转换为Dog类型 //判断对象值是否相等 if (age != other.age) return false; return true; }
*** END