一.1.继承的概念:
继承是类与类的一种关系。java中的继承是单继承。
2.继承的好处
子类拥有父类的所有属性和方法,private修饰的无效哦
实现代码复用
3.语法规则:
class子类 extends 父类
例:class Dog extends Animal{
…
}
4.创建子类时,可以选择要继承的父类
二.Java中的方法重写
1.子类可以继承父类的方法,但是有时,我们并不满意父类中的方法,所以要让子类可以重写父类继承的方法,当调用方法时,会优先调用子类的方法。
2.语法规则:
a.返回值类型
b.方法名
c.参数类型及个数
都要与父类继承的方法相同,才叫方法的重写
3.java中的继承初始化顺序
a.初始化父类再初始子类
b.先执行初始化对象中的属性,再执行构造方法中的初始化
代码示例:
父类:
package demo;
public class Animal {
public int age =10;
public String name;
public void eat(){
System.out.println("年龄:" +age+ "动物具有吃东西的能力");
}
public Animal(){
System.out.println("Animal类执行了");
age =20;
}
}
子类:
package demo;
public class Dog extends Animal {
public void eat(){
System.out.println("年龄"+age+"狗是可以吃东西的");
}
public Dog(){
System.out.println("Dog类执行了");
}
}
示例类:
package demo;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Animal animal = new Animal();
System.out.println("animal age:"+animal.age);
Dog dog = new Dog();
dog.age =10;
dog.name = "xiaogou";
dog.eat();
}
}
输出:
animal age:20
Animal类执行了
Dog类执行了
年龄10狗是可以吃东西的
三.java中的final使用
final关键字
使用final关键字做标识有“最终的”含义,意为不可修改,不可变化
final可以修饰类,方法,属性和变量
final修饰类,则该类不允许被继承
final修饰方法,则该方法不允许被覆盖(重写)
final修饰属性,则该类的属性不会进行隐式的初始化(类的初始化属性必须有值)
或在构造方法中赋值(但只能选其一)
final修饰变量,则该变量的值只能赋一次值,即变为常量
package demo;
final public class Animal {
public int age =10;
public String name;
public void eat(){
System.out.println("年龄:" +age+ "动物具有吃东西的能力");
}
public Animal(){
System.out.println("Animal类执行了");
age =20;
}
}
如上,final修饰类,则该类无法被继承。
如果final修饰方法,例如
package demo;
public class Animal {
public int age =10;
public String name;
final public void eat(){
System.out.println("年龄:" +age+ "动物具有吃东西的能力");
}
public Animal(){
System.out.println("Animal类执行了");
age =20;
}
}
如上,final修饰的方法,不能被重写
如果使用final修饰属性,则该属性的值只能赋一次。但是如果不给final修饰的属性不赋值,构造函数中也并没有初始化,则系统也不会帮我们自动初始化,此时系统会报错。
正确写法如下:
如果使用final修饰变量,则称为常量,不可改变此变量的值。
四.java中的super的使用
super关键字:在对象的内部使用,可以代表父类对象
1.访问父类的属性 super.age
2.访问父类的方法 super.eat
super的应用
子类的构造的过程当中必须调用其父类的构造方法。
如果子类的构造方法中没有显示调用父类的构造方法,则系统系默认调用父类无参的构造方法。
如果显示的调用构造方法,必须在子类的构造方法的第一行。
这种就是错误的。
如果子类构造方法中既没有显式调用父类的构造方法,而父类又没有无参的构造方法,则编译报错。
比如:我们在父类中定义一个有参的构造方法
package demo;
public class Animal {
public int age =10;
public String name;
public void eat(){
System.out.println("年龄:" +age+ "动物具有吃东西的能力");
}
// public Animal(){
// System.out.println("Animal类执行了");
// }
public Animal(int age){
this.age = age;
}
}
则子类的无参的构造方法就会报错
四.java中的object类
object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Obejct类。
Object类中的方法,适合所有子类
1.toString()方法
在obejct类里面定义toString()方法的时候返回的对象的哈希code码(对象地址字符串)
可以通过重写toString()方法表示出对象的属性
比如:测试类输出这个类的对象
package demo;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Animal animal = new Animal();
System.out.println("animal age:"+animal.age);
Dog dog = new Dog();
System.out.println(dog);
}
}
输出获得:demo.Dog@7852e922
而我们可以利用java自带的toString的方法,从而输出类对象的属性
在子类Dog类中
代码部分
package demo;
public class Dog extends Animal {
public int age= 20;
public void eat(){
System.out.println("年龄"+age+"狗是可以吃东西的");
}
public Dog(){
System.out.println("Dog类执行了");
}
public void method(){
System.out.println("父类属性"+super.age);
System.out.println("子类属性"+age);
}
@Override
public String toString() {
return "Dog [age=" + age + "]";
}
}
使用toString()方法以后再次在测试类中运行输出System.out.println(dog);
则显示
Dog [age=20]
2.equals()方法
比较的是对象的引用是否指向同一块内存地址。
Dog * dog =new Dog()
一般情况下比较两个对象时比较他的值是否一致,所以要进行重写。
那我们通过代码的方式验证一下:
package demo;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Animal animal = new Animal();
System.out.println("animal age:"+animal.age);
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("两个对象是不相同的");
}
System.out.println(dog);
}
}
验证输出为:两个对象是不相同的。相当于 “==” 判断,判断的是两个对象的内存地址。
如果要是判断两个对象的属性是否相同怎么办呢?我们要在子类下面重写equals方法,我们可以使用菜单栏Source,帮我们重写。
package demo;
public class Dog extends Animal {
public int age= 20;
public void eat(){
System.out.println("年龄"+age+"狗是可以吃东西的");
}
public Dog(){
System.out.println("Dog类执行了");
}
public void method(){
System.out.println("父类属性"+super.age);
System.out.println("子类属性"+age);
}
@Override
public String toString() {
return "Dog [age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)//首先要判断引用的值是否相同,引用的值判断的是两个引用的地址是否相同,如果两个引用的地址相同,那么就相当于两个指向的是同一个对象
return true;
if (obj == null)//如果另外一个对象是空值,那么肯定不是同一个对象
return false;
if (getClass() != obj.getClass())//getClass是可以得到一个类对象,理解为,如果我们new一个对象,那我们叫做 类的对象 ,如果我们getClass是称为类对象
return false;
Dog other = (Dog) obj;
if (age != other.age)//判断两个对象的值是否相等
return false;
return true;
}
}
getClass图示理解
再次运行测试类,则试验输出内容变更为:两个对象是相同的。