- 继承的特点: 子类能继承父类的非私有成员
- 继承后对象的创建: 子类的对象是由子类、父类共同完成的
继承的基本形式
package demo0319;
public class Father {
public int i;
public void print1(){
System.out.println("打印1");
}
// 私有化成员和变量时不能被继承的
private int j;
private void print2(){
System.out.println("打印2");
}
}
package demo0319;
// extends 关键字
public class Son extends Father{
public int m;
public void print3(){
System.out.println("打印3");
}
public int sum(){
i = 10;
// j是私有化变量,无法访问
// j = 20;
m = 20;
return m + i;
}
}
package demo0319;
public class Test {
public static void main(String[] args) {
Son s = new Son();
s.print1();
s.print3();
System.out.println(s.sum());
}
}
注解
- 继承就是用extends关键字,让一个类和另一个类建议起一种父子关系
- 子类可以继承父类非私有的成员
- 带继承关系的类,Java会有类和其父类,整合为一个大的设计图来一起创建类的对象
- 对象能直接访问什么成员,是由子父类这张大的设计图共同决定的,这张设计图对外暴露了什么对象,对象就可以访问什么成员
继承的好处
- 减少重复代码的使用
package demo0319;
public class Father {
// 父亲的姓氏
char surname = '赵';
// 户口本家庭住址
String address = "中国";
// 父亲的年龄
int age = 38;
String name = "四";
public void eat(){
System.out.println(surname + this.name + "要吃饭了~~");
}
public void run(){
System.out.println(surname + name + "准备去跑步~~");
}
}
package demo0319;
public class SonFirst extends Father{
// 第一个儿子
int age = 18;
String name = "五";
// 如果子类不认同父类的方法,可以重写父类的同名方法
public void eat(){
System.out.println(surname + name + "要吃饭了~~");
}
}
package demo0319;
public class SonSecond extends Father{
// 第二个儿子
int age = 12;
String name = "六";
// 如果子类不认同父类的方法,可以重写父类的同名方法
public void eat(){
System.out.println(surname + name + "要吃饭了~~");
}
}
package demo0319;
public class Test {
public static void main(String[] args) {
SonFirst SonF = new SonFirst();
SonSecond SonS = new SonSecond();
System.out.println(SonF);
System.out.println(SonS);
SonF.eat();
SonS.eat();
// 如果子类没有重写父类的方法,那么将执行父类的方法,可能会导致某些意外情况
SonF.run();
SonS.run();
System.out.println(SonF.address + SonF.age);
System.out.println(SonS.address + SonS.age);
}
}
注解
1.通过继承,可以将多个类重复的内容组装成这多个类共同的父类
2.由于使用了共同的父类,可以很大程度上减少重复代码的编写,且容易维护
3.如果子类和父类存在同名的公开方法,则使用子类的方法,如果某个方法,子类没有的情况下,才会去调用父类的方法
权限修饰符
- 作用: 就是用来限制类中的成员(成员变量、成员方法、构造器、代码块…)能够被访问的范围
修饰符 | 在本类中 | 同一个包下的其他类里 | 任意包下的子类里 | 任意包下的任意类里 |
---|---|---|---|---|
private | √ | |||
缺省 | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
单继承
- Java是单继承的,Java中的类只能直接继承一个父类,Java中的类不支持多继承,但是支持多层继承
- Object类是Java中所有类的祖宗
- 多层继承的子类,设计图由多层父类共同创建出来的
方法重写
当子类觉得父类中某个方法不好用,或者无法满足自己的需求时,子类可以重写一个和父类方法名称,参数列表一致的方法,Java将遵循就近原则,执行子类的方法
注意事项
- 使用Override注解,会自动检查重写格式是否正确,代码可读性会更好
- 子类重写父类方法时,访问权限必须大于或等于父类该方法的权限
- 重写的方法返回值类型,必须与父类的该方法返回值类型一样或者更小
- 私有方法、静态方法不能重写
- super可以通过子类访问父类的变量和方法,但是只能访问到当前父类的变量和方法,无法访问父类的父类
子类构造器
- 子类的全部构造器,都会先调用父类的构造器,在执行自己
- 父类的有参构造器,如果子类也存在相同的有参数构造器,将不会执行父类的有参构造器
- Java无法出现,只有父类的有参构造器,没有子类的相同的有参构造器
- 如果出现父类只有有参构造器,要在子类的开头,通过super来调用有参构造器,子类每个构造器都要使用super
- 可以通过this() 调用同一类的兄弟构造器,this()和super()不能同时出现在同一个构造器里面
package demo0319;
import java.util.ArrayList;
class Fathers{
String name;
int age;
double num;
public Fathers(){
System.out.println("父类的无参数构造器执行了");
}
public Fathers(int age){
System.out.println("父类的有参数构造器执行了~~");
this.age = age;
}
public Fathers(double num){
System.out.println("父类的有参数构造器执行了~~");
this.num = num;
}
}
class Son extends Fathers{
int age;
public Son(){
super();
System.out.println("子类的无参构造器执行了");
}
public Son(String name){
System.out.println("子类的有参数构造器执行了~~");
this.name = name;
}
public Son(int age){
System.out.println("子类的有参数构造器执行了");
}
public Son(int age, double num){
super(num);
System.out.println("子类的有参数构造器执行了");
}
}
public class Test {
public static void main(String[] args) {
Son s = new Son();
System.out.println("*********************");
Son s1 = new Son(18);
System.out.println("*********************");
Son s2 = new Son("童话");
System.out.println("*********************");
// 子类不能没有相关的有参构造器
// Son s3 = new Son(18.5);
Son s3 = new Son(12, 18.5);
System.out.println(s3.num);
}
}
package demo0319;
import java.util.ArrayList;
class Fathers{
String name;
int age;
double num;
public Fathers(){
System.out.println("父类的无参数构造器执行了");
}
public Fathers(int age){
System.out.println("父类的有参数构造器执行了~~");
this.age = age;
}
public Fathers(double num){
System.out.println("父类的有参数构造器执行了~~");
this.num = num;
}
}
class Son extends Fathers{
int age;
int num;
int count;
public Son(){
super();
System.out.println("子类的无参构造器执行了");
}
public Son(int age, int num){
// 通过this()可以自动调用相关的兄弟构造器
this(age, num, 180);
}
public Son(int age, int num, int count){
this.age = age;
this.num = num;
this.count = count;
}
}
public class Test {
public static void main(String[] args) {
Son s = new Son(119, 120, 110);
System.out.println("**************");
Son s1 = new Son(18, 18);
System.out.println(s1.count);
}
}