继承与多态
文章目录
继承
1.1为什么要有继承
继承用现实化的语言描述:事物之前当存在某种联系时就可以继承,例如QQ聊天平台五花八门,但是一些主要功能并没有被舍去只是在原先的基础上继承过来一部分,在自己新添加一部份。
1.2 继承的语法
用java语言去进行描述就是这样
继承的语法要求需要使用关键字extends
class person {
String name;//姓名
int age;//年龄
char sex;//性别
void eat() {
System.out.println(name + "吃饭");
}
void sleep() {
System.out.println(name + "睡觉");
}
}
class man extends person {
void toilet() {
System.out.println(name + "去男厕所");
}
}
class woman extends person {
void toilet() {
System.out.println(name + "去女厕所");
}
}
这里用person这个类作为父类,man和woman这两个类作为子类
如果不设计这个父类,代码就会出现大量重复,为了避免代码的复用使用继承就可以轻松解决
1.3 父类成员的访问
父类成员的访问使用直接使用变量名即可
如下
class person {
String name;//姓名
int age;//年龄
char sex;//性别
void eat() {
System.out.println(name + "吃饭");
}
void sleep() {
System.out.println(name + "睡觉");
}
}
class man extends person {
void toilet() {
System.out.println(name + "去男厕所");
}
}
public class test1 {
public static void main(String[] args) {
man ma = new man();
ma.toilet();
}
}
这里会有一个陷阱,如果当子类成员变量(成员方法)和父类成员变量(成员方法)相同时会使用哪一个
请看下面代码
class person {
String name="张山";//姓名
int age=25;//年龄
char sex;//性别
void eat() {
System.out.println(name + "吃饭");
}
void sleep() {
System.out.println(name + "睡觉");
}
}
class man extends person {
String name="李四";
void toilet() {
sleep();
System.out.println(name + "去男厕所");
}
void sleep() {
System.out.println(name + "睡觉测试");
}
void show() {
System.out.println(name);
System.out.println(age);
}
}
public class test1 {
public static void main(String[] args) {
man ma = new man();
ma.toilet();
}
}
这里的姓名,调用的方法就发生了改变,由此我们可以推出当父类成员变量(成员方法)与子类成员变量(成员方法)
相同时优先使用子类的
那有没有方法能够强制访问父类的呢?答案是有的
1.4 super关键字
使用super关键字搭配.点操作符就可以在子类中强制访问父类的属性例如:
class person {
String name="张山";//姓名
int age=25;//年龄
char sex;//性别
void eat() {
System.out.println(name + "吃饭");
}
void sleep() {
System.out.println(name + "睡觉");
}
}
class man extends person {
String name="李四";
void toilet() {
super.sleep();
System.out.println(super.name + "去男厕所");
}
void sleep() {
System.out.println(name + "睡觉测试");
}
void show() {
System.out.println(name);
System.out.println(age);
}
}
public class test1 {
public static void main(String[] args) {
man ma = new man();
ma.toilet();
}
}
这样就可以达到预期效果了
如果想在子类中访问父类属性用super关键字即可
1.5 构造方法
被继承了的子类创建构造方法时需要先帮助父类进行构造用代码去讲解比较容易理解如下:
class person {
String name = "张山";//姓名
int age = 25;//年龄
char sex;//性别
void eat() {
System.out.println(name + "吃饭");
}
void sleep() {
System.out.println(name + "睡觉");
}
person() {
System.out.println("父类的构造方法");
}
}
class man extends person {
String name = "李四";
man() {
super();
System.out.println("子类的构造方法");
}
void toilet() {
super.sleep();
System.out.println(super.name + "去男厕所");
}
void sleep() {
System.out.println(name + "睡觉测试");
}
void show() {
System.out.println(name);
System.out.println(age);
}
}
public class test1 {
public static void main(String[] args) {
man ma = new man();
}
}
在子类的构造方法时需要帮助父类构造则需要借用super关键字去调用父类的构造方法
帮助父类完成构造
在使用super时它需要放在子类构造方法的第一行,因为优先父类构造
子类父类同样支持构造方法的重载
class person {
String name = "张山";//姓名
int age = 25;//年龄
char sex;//性别
void eat() {
System.out.println(name + "吃饭");
}
void sleep() {
System.out.println(name + "睡觉");
}
person() {
System.out.println("父类的构造方法");
}
person(int a) {
System.out.println("测试");
}
}
class man extends person {
String name = "李四";
man() {
super(4);
System.out.println("子类的构造方法");
}
void toilet() {
super.sleep();
System.out.println(super.name + "去男厕所");
}
void sleep() {
System.out.println(name + "睡觉测试");
}
void show() {
System.out.println(name);
System.out.println(age);
}
}
public class test1 {
public static void main(String[] args) {
man ma = new man();
}
}
注意:
- 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构
造方法 - 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的
父类构造方法调用,否则编译失败。 - 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。
- super(…)只能在子类构造方法中出现一次,并且不能和this同时出现
1.6 super和this
this用来访问当前对象的对象,而super是用来访问父类的属性
它们都是java的关键字
当this调用子类的构造方法时不能和super同时存在
都不能访问静态的属性
1.7 protected 关键字
java中代表权限的关键字可以很形象的用修仙里面的炼气,筑基,结丹,元婴来描述
每到一个境界地位就直线上升
protected关键字对标于结丹,它则可以使在另一个包的子类访问父类的属性
下面用java来演示
先创建两个包
使用protected修饰几个父类属性用于测试
父类的权限必须设为public不然访问不了
package www.test;
public class person {
String name = "李四";//姓名
int age = 15;//年龄
protected void eat() {
System.out.println(name + "吃饭");
}
protected person() {
System.out.println("父类构造方法");
}
}
package www.test2;
import www.test.person;
public class man extends person{
public static void main(String[] args) {
man ma=new man();
ma.eat();
}
}
这里的构造方法必须设置为>=protected的权限,不然实例化对象时会出现编译出错
当没有被protected或public修饰的属性在子类是无法找到的
会编译出错因为没有权限找不到父类中的属性
1.8 final关键字
final关键字修饰变量时
变量在创建时就必须赋值,赋值之后是无法更改的
如果更改会出现编译错误
final在修饰类时,类是无法被继承的
都会出现编译错误
在修饰方法时方法不能进行重写
会出现编译错误
多态
2.1多态的语言描述
多态用通俗的语言去描述就是多种形态,在java中就是用不同对象去完成时会产生不同的结果。
2.2 多态的实现条件
- 必须在继承体系下
- 子类必须要对父类中方法进行重写
- 通过父类的引用调用重写的方法
2.3 多态的代码实现
第一步 写一个继承关系
class k {
void show() {
System.out.println("测试");
}
}
class d extends k{
}
第二部 子类对象对父类的方法进行重写
在重写时实例化对象需要向上转型
向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。
语法格式:父类类型 对象名 = new 子类类型()
public class Main {
public static void main(String[] args) {
k a=new d();
}
}
当有了向上转型后就需要构造重写
重写的构造必要条件 需要 返回值,方法名,参数列表 和父类的方法都一样才可,和重载有的本质的区别不要混淆
public class Main {
public static void main(String[] args) {
k a=new d();
}
}
class k {
void show() {
System.out.println("测试");
}
}
class d extends k{
void show() {
System.out.println("测试2");
}
}
这样就是重写了父类的方法
当通过父类引用调用方法时就会去调用子类的方法
第三步 通过父类的引用调用方法
public class Main {
public static void main(String[] args) {
k a=new d();
a.show();
}
}
class k {
void show() {
System.out.println("测试");
}
}
class d extends k{
void show() {
System.out.println("测试2");
}
}
运行结果为
这样就写好了实际应用场景看开发需求
以上则是全部内容。