一、继承
1、继承的概念:
继承是类与类的一种关系,如狗类是动物类的继承类
注:Java中的继承是单继承,即一个类只有一个父类
2、继承的好处
子类拥有父类的所有属性和方法 private修饰的方法和属性无效
实现代码复用
3、语法规则
class 子类 extends 父类
public class Animal{
public int age;
public String name;
public void eat(){
System.out.println("动物具有吃东西的能力");
}
}
public class Dog extends Animal{
}
//测试类
public class Initial{
public static void main(String[] args){
Dog dog = new Dog();
dog.age = 10;
dog.name = "mark";
dog.eat();
}
}
二、方法重写
1、定义
如果子类对继承父类的方法不满意,是可以重写父类继承的方法的,当调用方法时会优先调用子类的方法。
2、语法规则:
- 返回值类型
- 方法名
- 参数类型及个数
都要与父类继承的方法相同,才叫方法的重写
public class Dog extends Animal{
public void eat(){
System.out.println("年龄"+age+"狗是可以吃东西的");
}
}
//测试类
public class InitialClass{
public static void main(String[] args){
Dog d = new Dog();
d.age = 10;
d.eat();
}
}
三、继承初始化顺序
- 初始化父类再初始子类
- 先执行初始化对象中属性,再执行构造方法中的初始化
例如:
//父类
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 Dog(){
System.out.println("Dog类执行了");
}
//测试类
public class Initial{
public static void main(String[] args){
Animal animal = new Animal();
System.out.println("animal age:"+animal.age);
Dog dog = new Dog();
dog.age = 10;
dog.name = "mark";
dog.eat();
}
}
运行结果:
Animal类执行了
animal age:20
Animal类执行了
Dog类执行了
动物具有吃东西的能力
即优先创建父类对象,再创建子类对象
四、final关键字
使用final关键字做标识有”最终的“含义
final可以修饰类、方法、属性和变量。final修饰类,则该类不允许被继承;final修饰方法,则改方法不允许被覆盖(重写);final修饰属性,则该类的属性不会进行隐式的初始化(类的初始化属性必须有值)或在构造方法中赋值(但只能选其一);final修饰变量,则该变量的值只能赋一次值,即变为常量
五、super关键字
super关键字:在对象的内部使用,可以代表父类对象。
访问父类的属性 super.age
访问父类的方法 super.eat()
//父类
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 int age = 20;
public void eat(){
System.out.println("狗具有吃骨头的能力");
}
public Dog(){
//super.();可写可不写,不写的时候隐式地调用父类的构造方法
System.out.println("Dog类执行了");
}
public void method(){
System.out.println(super.age);
System.out.println(age);
}
}
//测试类
public class Initial{
public static void main(String[] args){
Dog dog = new Dog();
dog.method();
}
}
运行结果:
Animal类执行了
Dog类执行了
10
20
注意:
- 子类的构造的过程当中必须调用其父类的构造方法;
- 如果子类的构造方法中没有显式调用父类的构造方法,则系统默认调用父类无参的构造方法;
- 如果显式地调用构造方法,必须在子类的构造方法的第一行;
- 如果子类构造方法中既没有显式调用父类的构造方法,而父类又没有无参的构造方法,则编译出错。
例如:
//父类
public class Animal{
public int age = 10;
public String name;
public void eat(){
System.out.println("动物具有吃东西的能力");
}
/*
public Animal(){
System.out.println("Animal类构造方法执行了");
}
*/
//定义了一个有参的构造方法,系统就不会再生成无参的构造方法
public Animal(int age){
this.age = age;
}
}
//子类
public class Dog extends Animal{
public int age = 20;
public void eat(){
System.out.println("狗具有吃骨头的能力");
}
public Dog(){
//super.();隐式调用父类的构造方法 !!!!!!!!!!!!!此时会出现编译报错
System.out.println("Dog类执行了");
}
public void method(){
System.out.println(super.age);
System.out.println(age);
}
}
//测试类
public class Initial{
public static void main(String[] args){
Dog dog = new Dog();
dog.method();
}
}
六、Object类
Object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object类。
Object类中的方法,适合所有子类。
1、toString()方法
在Object类里面定义toString()方法的时候返回的对象的哈希code码(对象地址字符串),可以通过重写toString()方法表示出对象的属性。
//测试类
public class Initial{
public static void main(String[] args){
Dog dog = new Dog();
System.out.println(dog);
}
}
运行结果:
Animal类执行了
Dog类执行了
com.imooc.Dog@61de33
Eclipse可以帮助我们自动生成重写的方法。Source->Generate toString()..
public class Dog extends Animal{
public int age = 20;
public void eat(){
System.out.println("狗具有吃骨头的能力");
}
public Dog(){
System.out.println("Dog类执行了");
}
@Override
public String toString(){
return "Dog [age="+age+"]";
}
}
运行结果:
Dog类执行了
Dog [age=20]
2、equals()方法
比较的是对象的引 用是否指向同一块内存地址
Dog dog = new dog(),dog不是对象,是对象所在的地址
一般情况下比较两个对象时比较他的值是否一致,所以要进行重写。
//父类
public class Animal extends Object{
public int age = 10;
public String name;
public void eat(){
System.out.println("动物具有吃东西的能力");
}
}
//子类
public class Dog extends Animal{
public int age = 20;
public void eat(){
System.out.println("狗具有吃骨头的能力");
}
public void method(){
eat();
}
}
//测试类
public class Initial{
public static void main(String[] args){
Dog dog = new Dog();
dog.age = 15;
Dog dog2 = new Dog();
dog2.age = 15;
if(dog.equals(dog2)){
System.out.println("两个对象是相同的");
}else{
System.out.println("两个对象是不相同的");
}
if(dog==dog2){
System.out.println("两个对象是相同的");
}else{
System.out.println("两个对象是不相同的");
}
}
运行结果:
两个对象是不相同的
两个对象是不相同的
==判断两个基本数据类型的值是否相同;如果判断的是引用的值是否相同,也是比较内存地址。
所以,如果要相比较两个对象的数据的值师傅相同该怎么办呢?要重写equals()方法。Eclipse在Source->Generate hashcode() and equals()…可以生成。
如下:
@Override
public boolean equals(Object obj){
if(this == obj)//判断两个引用的地址是否相同
return true;
if(obj == null)//如果另外一个地址是空值,就不需要比较了,一定是不相等的
return false;
if(getClass()!=obj.getClass())//getClass()可以得到一个类对象。new一个对象的时候,我们得到的是类的对象。类对象描述的是类的代码信息。类的对象关注的是类的属性值的信息,比较见下图。
return false;
Dog other = (Dog) obj;
if(age!=other.age)
return false;
return true;
}
\\测试
if(dog.equals(dog2)){
System.out.println("两个对象是相同的");
}else{
System.out.println("两个对象是不相同的");
}
运行结果:
两个对象是相同的