3 minutes
Java面向对象之继承 笔记
Java面向对象之继承
类的继承机制
继承的的作用
-
继承的作用:减少重复的冗余的相同属性和方法
-
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中
-
那么多个类无需再定义这些相同属性和行为,只要继承那个类即可
public class Person
{
// 姓名
private String name;
// 年龄
private int age;
public void setName(String name)
{
this.name = name;
}
public void setAge(int age)
{
this.age = age;
}
public void eat()
{
System.out.println("吃饭");
}
}
public class Student extends Person
{
}
子类和父类的继承机制
- 继承关系是两个类,一个为子类(派生类),一个父类(基类)。
- 子类继承父类,使用关键字extends来表示
- extends的意思是“扩展”,子类是对父类的扩展
- java中类只有单继承,没有多继承(一个儿子只有一个直接的爸爸,但是爸爸可以有多个儿子)
Java的单继承
- Java不支持多继承,只允许一个类直接继承另一个类
- 子类只能有一个父类,extends关键字后面只能有一个类名
Java继承的顶级父类:Object类简介
- Object类是Java中所有类的始祖
- Java中的每一个类都是由它扩展而来,但是并不需要明确写出要继承它
- 自然的,所有Java类都拥有了其方法
toString()
方法
该方法用来返回对象的字符串表示形式
public class Person
{
// 姓名
private String name;
// 年龄
private int age;
public String toString()
{
return "Person["+name+","+age+"]";
}
public static void main(String[] args)
{
Person p = new Person();
p.name = "张五";
p.age = 20;
System.out.println(p.toString());
}
}
equals(Object obj)
方法
该方法用来判断两个对象是否相同
如果没有被重写过,其与==等价
public class PersonOne
{
public static void main(String[] args)
{
PersonOne p1 = new PersonOne();
PersonOne p2 = new PersonOne();
System.out.println(p1.equals(p2));
}
}
hashCode()
方法
Object类的hashCode方法是返回对象存储地址
public class PersonOne
{
public static void main(String[] args)
{
PersonOne p1 = new PersonOne();
System.out.println(p1.hashCode());
PersonOne p2 = new PersonOne();
System.out.println(p2.hashCode());
}
}
对象向上转型
引用类型的转换
- 子类转换成为父类,向上转型
- 格式:父类名称 对象名称 = new 子类名称();
- 含义:把创建的子类对象当做父类看待和使用
public class Person
{
public void run()
{
System.out.println("Person Run");
}
}
public class Student extends Person
{
public void eat()
{
System.out.println("Son eat");
}
}
public class Application
{
public static void main(String[] args)
{
// person(父类引用)可以指向子类
// 向上转型
Person s2 = new Student();
s2.run();
// 但不能调用子类特有的方法
//s2.eat();
}
}
对象向下转型
引用类型转换
- 父类转换为子类,向下转型
- 子类 引用 = (子类)父类对象
- 强制类型转换
public class Person
{
public void run()
{
System.out.println("Person Run");
}
}
public class Student extends Person
{
public void eat()
{
System.out.println("Son eat");
}
}
public class Test
{
public static void main(String[] args)
{
Person p = new Student();
// 报错
// p.eat();
// 向下转型
Student s = (Student) p;
s.eat();
}
}
对象向下转型注意:
问题:可能会出现ClassCastException异常
public class Person
{
public void run()
{
System.out.println("Person Run");
}
}
public class Student extends Person
{
public void eat()
{
System.out.println("Son eat");
}
}
package TestDemo;
public class Test1
{
public static void main(String[] args)
{
Person p = new Person();
Student s = (Student) p;
s.eat();
}
}
super关键字
super在继承构造函数中定义和作用
- 在继承中子类的构造函数必须依赖父类提供的构造函数
- super(参数列表)访问父类的构造函数
- super调用父类的构造函数,必须在构造函数的第一行
如果父类的构造函数是无参构造函数,可以默认不写super关键字
- 在继承中子类的构造函数必须依赖父类提供的构造函数
public class Person
{
private String name;
private int age;
public Person(String name, int age)
{
}
}
public class Student extends Person
{
public Student()
{
// 1. 如果父类提供的只有有参数的构造函数,子类的构造必须依赖父类提供的现有构造函数
// 2. super(参数列表)去访问父类的提供的构造函数,必须明确写出参数
// 3. super必须在第一行
super("小张", 20);
}
}
super访问父类的属性
- 在子类的方法或构造器中,通过使用super属性
- 特殊情况:当子类和父类中定义了同名的属性时,想调用父类中声明的属性,就需要通过super.属性的方式来声明调用的是父类中声明的属性
public class Person
{
// 身份证号
int id = 1001;
}
public class Student extends Person
{
// 学生证号
int id = 80;
public void show()
{
System.out.println("身份证号是"+super.id+",学生证号是"+id);
}
}
package super_Demo;
public class Test
{
public static void main(String[] args)
{
Student s = new Student();
s.show();
}
}
super访问父类的方法
在子类的方法或构造器中,通过使用super.方法名
public class Person
{
public void eat()
{
System.out.println("人都要吃饭");
}
}
public class Student extends Person
{
public Student()
{
// 访问父类的方法
super.eat();
}
public static void main(String[] args)
{
Student s = new Student();
}
}
super和this区别
- super()调用父类的构造函数,必须在构造函数的第一行
- this()调用本类的构造函数,必须在构造函数的第一行
- super()和this()不能同时调用构造函数
代表对象不同
- this:本身调用者这个对象
- super:代表父类对象的引用
前置
- this:没有继承也可以使用
- super:只能在继承条件下才能使用
构造方法
- this():本类的构造
- super():父类的构造
final关键字
final关键字修饰变量
- final关键字修饰的变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能修改
- final关键字修饰的变量,如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象
- final修饰的变量都是常量
- final可以修饰局部变量
final关键字修饰方法
-
final修饰的成员方法不能被子类重写
当父类的方法为final时,子类不能与父类有方法名、参数类型、参数个数及参数顺序都一样的方法
- 父类方法为private修饰符的final方法
public class Person
{
private final void show()
{
System.out.println("Person:show");
}
}
public class Student extends Person
{
public final void show()
{
System.out.println("Student:show");
}
}
public class Test
{
public static void main(String[] args)
{
Person person = new Person();
Student stu = new Student();
//private的方法仅本类可见,该方法不可见
//person.show();
stu.show();
}
}
final修饰类
- final修饰的类不能被子类继承
- final类中的成员方法也默认为final
- final类中的变量值是可以改变的
Read other posts