1.继承关键字extends
java中继承特点:
在Java中,类只支持单继承,不允许多继承,也就是说一个类只能有一个直接父类
多个类可以继承一个父类
在Java中,多层继承是可以的,即一个类的父类可以再去继承另外的父类,例如C类继承自B类,而B类又可以去继承A类,这时,C类也可称作A类的子类
子类只能获取父类非私有成员
super:可以获取父类的成员变量和成员方法,用法和this是相似的
package com.daigua12;
public class ExtendsDemo {
public static void main(String[] args) {
Dota1 d = new Dota1();
d.start();
d.stop();
Lol1 l = new Lol1();
l.start();
l.stop();
}
}
class Game {
String name;
double version;
String agent;
public static void start() {
System.out.println("游戏启动了!");
}
public static void stop() {
System.out.println("游戏停止了!");
}
}
class Dota1 extends Game{
}
class Lol1 extends Game{
}
2.访问变量的顺序
package com.daigua12;
/*
* 继承中成员变量的特点
* 子类只能获取父类非私有成员
* 子父类中成员变量的名字不一样直接获取父类的成员变量
* 子父类中成员变量名字是一样的获取的是子类的成员变量
*
* 就近原则:谁离我近我就用谁
* 如果有局部变量就使用局部变量
* 如果没有局部变量,有子类的成员变量就使用子类的成员变量
* 如果没有局部变量和子类的成员变量,有父类的成员变量就使用父类的成员变量
* 啥都没有,出错了!!!
*
* super:可以获取父类的成员变量和成员方法,用法和this是相似的
*/
public class ExtendsDemo3 {
public static void main(String[] args) {
Kid3 k = new Kid3();
k.show();
}
}
class Dad3 {
String name = "建霖";
}
class Kid3 extends Dad3 {
String name = "四葱";
public void show() {
String name = "五葱";
System.out.println(super.name);
System.out.println(this.name);
System.out.println(name);
}
}
3.方法重写
package com.daigua12;
/*
* 方法重写的应用场景:当父类的方法不能完全满足子类使用,这个时候子类重写父类的方法,
* 并可以在方法中使用关键字super调用父类的方法,这样做即可以保有父类的功能,也可以拥有子类特有的功能
* 方法重写的注意事项:
* 不能重写父类私有的方法
* 权限必须大于等于父类方法的权限
*
* 注解:@
*
*/
public class ExtendsDemo5 {
public static void main(String[] args) {
NewPhone np = new NewPhone();
np.call();
}
}
class Phone {
void call() {
System.out.println("打电话");
}
}
class NewPhone extends Phone {
@Override
public void call() {
super.call();
System.out.println("录音");
// System.out.println("打电话");
// super.call();
}
}
4.构造方法调用顺序
package com.daigua12;
/*
* 继承中构造方法的执行顺序
* 在子父类中,创建子类对象,调用子类的构造方法,
* 在子类的构造方法的第一行代码如果没有调用父类的构造或者没有调用子类的其他构造,则默认调用父类无参构造
* 为什么要调用父类构造?
* 因为需要给父类的成员变量初始化
* 肯定会先把父类的构造执行完毕,在去执行子类构造中的其他代码
*
* 我是父类无参构造 --- 我是子类有参构造 --- 我是子类无参构造
*/
public class ExtendsDemo6 {
public static void main(String[] args) {
// Die d = new Die();
Zi6 z = new Zi6();
}
}
class Die6 {
public Die6() {
System.out.println("我是父类无参构造");
}
public Die6(int num) {
System.out.println("我是父类有参构造");
}
}
class Zi6 extends Die6 {
public Zi6() {
// super(1);
// super();
this(1);// 不会再调用父类的无参构造了
System.out.println("我是子类无参构造");
}
public Zi6(int num) {
// 会默认调用父类无参构造
System.out.println("我是子类有参构造");
}
}
5.抽象类
package com.daigua12;
public class AbstractDemo {
public static void main(String[] args) {
Cat c = new Cat();
c.eat();
}
}
// 抽象类,一般作为基类
abstract class Animal {
public abstract void eat();
// 非抽象方法,子类可以不用重写
public void run() {
System.out.println("running");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("小猫吃鱼!");
}
}
6.抽象类成员特点
package com.daigua12;
/*
* 抽象类的成员特点:
* 成员变量
* 可以有成员变量
* 可以有常量
* 成员方法
* 可以有抽象方法
* 可以有非抽象方法
* 构造方法
* 可以有构造方法的,需要对抽象类的成员变量进行初始化
*
* final:修饰类、成员变量、成员方法
*/
public class AbstractDemo3 {
public static void main(String[] args) {
Dog d = new Dog();
d.barking();
}
}
abstract class Animal2 {
String name = "哮天犬";
// final变量只能初始化一次
final int num = 10;
public Animal2() {
System.out.println("我是抽象类的构造方法");
}
public abstract void eat();
public void run() {
}
}
class Dog extends Animal2 {
public void barking() {
System.out.println(name);
System.out.println(num);
}
@Override
public void eat() {
// TODO Auto-generated method stub
}
}
7.抽象类案例1-老师
要求:
老师类:
属性:姓名,年龄,性别
行为:讲课
基础班老师:
属性:姓名,年龄,性别
行为:讲基础班课程
就业班老师:
属性:姓名,年龄,性别
行为:讲就业班课程
package com.daigua12;
/*
* 老师类:
属性:姓名,年龄,性别
行为:讲课
基础班老师:
属性:姓名,年龄,性别
行为:讲基础班课程
就业班老师:
属性:姓名,年龄,性别
行为:讲就业班课程
* */
public class AbstractTeacher {
public static void main(String[] args) {
BasicTeacher b1 = new BasicTeacher("鲁迅", 18, "男");
b1.action();
WorkTeacher w1 = new WorkTeacher("菩提老祖", 1008, "未知");
w1.action();
}
}
abstract class Teacher {
String name;
int age;
String gender;
public Teacher(String name, int age, String gender) {
this.age = age;
this.gender = gender;
this.name = name;
}
public abstract void action();
}
class BasicTeacher extends Teacher {
public BasicTeacher(String name, int age, String gender) {
// TODO Auto-generated constructor stub
super(name, age, gender);
}
@Override
public void action() {
// TODO Auto-generated method stub
System.out.println("讲基础班课程");
}
}
class WorkTeacher extends Teacher {
public WorkTeacher(String name, int age, String gender) {
// TODO Auto-generated constructor stub
super(name, age, gender);
}
@Override
public void action() {
// TODO Auto-generated method stub
System.out.println("讲就业班课程");
}
}
8.抽象类的细节问题
A:抽象类关键字abstract可以和哪些关键字共存?
1.private:
私有的方法子类是无法继承到的,也不存在覆盖,而abstract和private一起使用修饰方法,abstract既要子类去实现这个方法,而private修饰子类根本无法得到父类这个方法。互相矛盾。
2.final:
抽象类不能和final共存,因为抽象类自身无法创建对象,我们需要通过子类创建对象,一旦抽象类使用final关键字,那么抽象类就没有子类
抽象方法不能和final共存,因为抽象方法后期需要被子类重写,一旦加final无法重写
3.static:
抽象方法不能和static关键字共存,因为一旦加static我们就可以通过类名直接访问抽象方法,由于抽象方法没有方法体,没有任何意义,也不允许这样做
B:抽象类中是否可以不定义抽象方法?
是可以的,那这个抽象类的存在到底有什么意义呢?不让该类创建对象,方法可以直接让子类去使用
C:抽象类是否有构造函数?
有,抽象类的构造函数,是由子类的super语句来调用,用于给抽象类中的成员初始化