1、语法
- 关键字:extends
- 格式:
public class 子类名 extends 父类名{
}
2、子类继承父类那些东西?
- 所有
- 属性
- 代码块
- 构造器
- 方法
3、子类以及子类对象可以调用到继承的哪些东西?
3.1 4个控制修饰符总结:
- private——仅对本类可见
- public——对外部完全可见
- protected——对本包和所有子类可见
- 缺省——对本包可见
3.2 本包:
public class Student{
public String name;
private int id;
protected int age;
int score;
public void exam(){
System.out.println("父类定义的考试方法");
}
}
public class UNStudent extends Student{
public void printInfo(){
/**
* 在同包的子类中
* private不可以调用
* public、protected、缺省的可以调用
*/
System.out.println("name:"+name);
// System.out.println("id:"+id);
System.out.println("age:"+age);
System.out.println("score:"+score);
}
public void exam(){
System.out.println("子类重写的考试方法");
}
}
public class StuManage {
public static void main(String[] args) {
//在同包的非子类中,子类对象可以调用除private的属性
UNStudent unstu1 = new UNStudent();
unstu1.name="hunter0";
unstu1.age=23;
unstu1.score=100;
//不同包的子类 在与父类同包的非子类中可以调用public 和Protectd
MidStudent midstu1 = new MidStudent();
midstu1.name = "hunter1";
midstu1.age= 17;
}
}
3.3 不同包:
public class MidStudent extends Student {
public void printInfo(){
/**
* 在不同的包的子类中
* private和缺省的不可以调用
* public和protected可以调用
*/
System.out.println("name:"+name);
// System.out.println("id:"+id);
System.out.println("age:"+age);
// System.out.println("score:"+score);
}
public static void main(String[] args) {
// 在不同包的子类中 子类对象可以调用public 修饰的属性
UNStudent unstu1= new UNStudent();
unstu1.name="";
// unstu1.age=20;
// unstu1.score=20;
MidStudent midstu1= new MidStudent();
midstu1.name="";
midstu1.age=20;
}
}
public class StuManage {
public static void main(String[] args) {
//在不同包的非子类中,子类对象可以调用public修饰的属性
UNStudent unstu1 = new UNStudent();
unstu1.name="hunter0";
// unstu1.age=20;
// unstu1.score=20;
MidStudent midstu1 = new MidStudent();
midstu1.name = "hunter1";
// midstu1.age= 17;
}
}
4、方法重写
4.1 语法:
- 在子类中,出现了和父类方法声明完全一样的方法(方法返回值类型一样,方法名一样,参数列表一样)。
4.2 格式:
- 除方法体以为,其他和父类方法声明一样。
4.3 作用:
- 重写以后,当创建子类对象以后,通过子类对象调用父类中的同名参数的方法时,实际执行的是子类重写父类的方法。
- 如果需要调用父类的方法使用super关键字
5、强制转型(向下转型):
- 将一个类型强制转换成另外一个类型的过程
- int i = (int)1.2
- 属于不安全转型,具有风险
- 需要先确认传入的对象的类型(不是变量名的类型)
- instanceof()
- getClass()
6、自动转型(向上转型):
- 子类对象可以自动转型为父类类型
- A a = new B(); //前提:A是B的父类
- 安全的
- 作用:
- 提高抽象化,让具体具备更好的兼容性
- 数据存储 比较等方面更方便
- 系统的设计上更有结构性,可以在父类中定义一些抽象的功能属性
- 子类对象自动转型之后,调用重写的方法?子类的
- 自动转型之后,不能调用子类独有的方法
public class StuManage {
public static void main(String[] args) {
//自动转型
Student stu1 = new UNStudent();//有
stu1.exam();
//stu1.printInfo(); //隐藏
//强制转型
UNStudent unstu2 = (UNStudent) stu1;//隐藏的方法 解除限制
unstu2.exam();
unstu2.printInfo();
//强制转型
Student stu2 = new Student();//无
UNStudent unstu3 = (UNStudent) stu2;
unstu3.exam();
unstu3.printInfo();//无中生有
}
}
7.思考题
7.1方法重写时 :访问修饰符 返回值类型 参数类型 可不可以修改
①子类重写的的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
②子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
特殊情况:子类不能重写父类中声明为private权限的方法
③返回值类型:
父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
父类被重写的方法的返回值类型是A,则子类重写的方法的返回值类型可以是A类或A类的子类
父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)
④子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
7.2重写 与 重载的区别?
①二者的概念:
重写:在子类中,出现了和父类方法声明完全一样的方法
重载:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
②重载和重写的具体规则
重写:子类中,相同方法名,方法返回值类型一样,方法名一样,参数列表一样
重载::同一个类、相同方法名,参数列表不同:参数个数不同,参数类型不同
③重载:不表现为多态性
重写:表现为多态性
重载,是指允许存在多个同名方法,而这些方法的参数不同。 编译器根据方法不同的参数表, 对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。 它们的调用地址在编译期就绑定了。 Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。
所以: 对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,
这称为“早绑定”或“静态绑定” ;而对于多态,只等到方法调用的那一刻, 解释运行器才会确定所要调用的具体
方法,这称为“晚绑定”或“动态绑定” 。
7.3构造方法? 子类在创建对象时 调用属性、构造方法以及父类的属性、构造方法
public class User {
String name;
{
System.out.println("父类代码块");
}
static {
System.out.println("父类静态代码块");
}
public User(){
System.out.println("父类构造方法1");
}
public User(String name) {
this.name = name;
System.out.println("父类构造方法2");
}
// 静态方法
public static void getName(){
System.out.println("父类静态方法 ");
}
public void getInfor(){
System.out.println("父类普通方法");
System.out.println(name);
}
}
public class Son extends User {
int id;
{
System.out.println("子类代码块");
}
static {
System.out.println("子类静态代码块");
}
public Son() {
System.out.println("子类构造方法1");
}
public Son(String name, int id) {
super(name);
this.id = id;
System.out.println("子类构造方法2");
}
// 静态方法
public static void getName(){
System.out.println("子类静态方法 ");
}
public void getInfo(){
System.out.println("子类普通方法");
System.out.println(name+id);
}
public static void main(String[] args) {
Son son1 = new Son();
System.out.println("****************************");
Son son2 = new Son("hunter",1111111);
System.out.println("****************************");
System.out.println(son2.name);
System.out.println(son2.id);
}
}
执行结果:
父类静态代码块
子类静态代码块
父类代码块
父类构造方法1
子类代码块
子类构造方法1
****************************
父类代码块
父类构造方法2
子类代码块
子类构造方法2
****************************
hunter
1111111