十一.类和对象(3)继承+重载与重写+ super,final关键字+ 抽象类+接口

17.12继承

1.java三大特性之一:继承

继承是类和类之间的关系,至少需要两个类

格式:

class B extends A {

}

B继承于A,A是B的父类(超类,基类),B是A的子类

package com.qfedu.b_extends;

class Father {
	String name;
	int age;
	//行为
	public void eat () {
		System.out.println("吃大盘鸡拌面");
	}
}
//使用了extends以后  Son 类就继承了Father这个类
//就意味着我Son类可以使用Father类下面某些属性和某些方法
class Son extends Father{
	
}

public class Demo1 {
	public static void main(String[] args) {
		Son son = new Son();
		//发现继承以后,可以使用父类一些属性
		son.name = "小骚磊";
		son.age = 1;
		System.out.println(son.name);
		System.out.println(son.age);
		son.eat();
		
	}

}
2.继承的内容

1.成员变量(属性)

​ 公开的和默认的属性,子类可以继承使用

​ 私有的成员变量,子类无法使用

2.成员方法

​ 公开的和默认的,子类可以继承使用,私有的子类无法使用

即:凡是私有的都无法继承

3.构造方法

​ 先执行父类的构造方法,在执行子类的构造方法

注意:

  1. 子类和父类的构造方法形式要保持一致。即父类子类都有或没有无参构造,或者都是有参构造,子类可以通过在内部首行使用super(形参)的形式将参数传给父类。

  2. java中的继承是单继承,只有一个父类,可以多层继承,但不能多重继承

package com.qfedu.c_extends;

class A {
	
}
class B extends A{
	
}
class C extends B {
	
}
public class Demo4 {
	public static void main(String[] args) {
		
	}

}

3.继承中父子类的内存分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdEa56zm-1658908421037)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220725171735679.png)]

4.重写【重点】

Override

目的:

​ 子类可以继承父类非私有化的方法,有时候父类的方法无法满足子类的需求,就需要重写父类非私有的方法

要求:

​ 1.必须有继承关系

  1. 父类方法必须是非私有化的
  2. 子类中重写父类方法除了方法体不一样,其他都一样
  3. 重写必须写在子类中
package com.qfedu.d_override;

class Father {
	public void eat () {
		System.out.println("吃粗粮。。。。。。");
	}
	public void driver () {
		System.out.println("开拖拉机。。。。。");
	}
}
//当父类不能满足子类的需求的话可以在子类中重写父类的方法
class Son extends Father {
	//重写的时候在子类中 只需要打上方法的名字一敲回车即可
	//重写的方法  和父类 的 返回值  参数  方法名字 一模一样,但是方法体不一样的
	@Override//是重写的严格限定,只要有这个,就证明咱们下面的这个方法
	//就是重写的方法,告知程序员 此时eat方法是重写的不是自己独有的
	public void eat() {
		System.out.println("吃白面馒头......");
	}
	@Override
	public void driver() {
		System.out.println("开小汽车");
	}
	
}
public class Demo1 {
	public static void main(String[] args) {
		Son son = new Son();
		son.eat();
		son.driver();
		//重写的话,是不影响父类的方法的
		Father father = new Father();
		father.eat();
		father.driver();
	}

}
5.重载【overload】

在同一个类中存在的名字相同,但参数列表不一样的方法,这叫重载

总结:

1.方法的重载必须在同一个类中

2.方法名要一样

3.方法的参数类型必须不一样

4.方法返回值可以不一样

5.无参构造和有参构造也是一种重载

6.super关键字(不重要)

只能用于继承,并在子类中使用,代表父类对象

this:

​ 代表当前类对象

​ 可以调用当前类的属性和方法

​ 可以调用构造方法

super:

​ 1.代表的是当前类的父类

​ 2.可以调用父类中非私有的属性和方法(实际在内存中还是在子类对象内,即super和this差不多)

​ 3.父子类有同名属性或父类方法被重写后,要想调用原父类属性或方法,可以用super.属性/方法名() 调用

​ 4.在子类构造器中使用super(参数)指定调用父类有参构造器,不指定默认调用父类无参构造

package com.qfedu.b_super;
class Father1 {
	String name;
	public Father1 () {
		System.out.println("Father1的无参构造");
	}
	public Father1 (String name) {
		System.out.println("Father1有参构造");
	}
}
class Son1 extends Father1 {
	//在子类中无论你写了有参构造和无参构造,都要去执行父类的无参构造
	//除非你自己调用父类有参构造方法
	public Son1(String name) {
		//在调用父类的无参构造方法
		//super();
		super("狗蛋");
	}
}
public class Demo2 {
	public static void main(String[] args) {
		Son1 son1 = new Son1("狗蛋");
		
	}

}

17.13抽象类【重要】

所有对象都可以通过类创建,但不是所有类都可以创建对象。

一个类中没有足够完整的信息来描述具体对象

在java中用关键字abstract修饰的类,这个类叫抽象类

1.abstract关键字

abstract修饰的类叫做抽象类,修饰的方法叫做抽象方法

注:abstract只能修饰类和方法

格式:

abstract class 类名 {
	//普通方法;
	public void eat() {
	...
	}
	
	//抽象方法
	public abstract void sleep();
}

抽象类中可以有普通方法和抽象方法,抽象方法用abstract修饰,不是完整的方法,没有大括号和方法体

注意事项:

  1. 一个类如果用abstract修饰,就是一个抽象类

  2. 抽象类中可以有普通成员方法和抽象方法

  3. 抽象方法没有方法体,是不完整的方法

  4. 抽象类不能被实例化

  5. 可以写一个普通的类去继承抽象类

  6. 在子类中必须要实现(重写)抽象类中所有的抽象方法

  7. 非抽象方法可以不重写

  8. 一个抽象类可以继承另一个抽象类

  9. 一个抽象类可以继承一个非抽象类

package com.qfedu.c_abstract;

class Cell {
	public void add () {
		System.out.println("分裂");
	}
}
abstract class Animal extends Cell{
	public abstract void run();
}
abstract class Monkey extends Animal{//抽象类
	public void call () {//普通的成员方法
		System.out.println("咿咿呀呀.......");
	}
	public abstract void eat();
	public abstract void sleep();
}
class People extends Monkey {

	@Override
	public void eat() {
		// TODO Auto-generated method stub
		System.out.println("吃肉!!!");
	}

	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("躺着睡。。。");
	}
	@Override
	public void call() {
		System.out.println("嘻嘻哈哈说话");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("人站立奔跑。。。");
	}
	
}
public class Demo2 {
	public static void main(String[] args) {
		People people = new People();
		people.add();
	}
}

17.14final关键字

final:最终的,

用法:

​ 1.修饰成员变量

​ 使用final修饰的成员变量一定要赋值(初始化),而且不能 修改

​ 2.修饰局部变量

​ 使用final修饰局部变量的时候,可以先对变量不赋值,使 用前赋值,但是一旦赋值后就无法更改

​ 3.修饰成员方法

​ final修饰的成员方法不能被重写,牵涉到继承

​ 4.修饰一个类

​ final修饰的类不能被继承

​ 5.修饰对象的引用

​ final Person person = new Person();

​ 一旦使用final修饰person 对象引用是一个固定的内存地 址,无法改变

package com.qfedu.d_final;

 class Person {
	final String name = "狗蛋";
	
	public void test () {
		 final int i;
		i = 30;
		//i = 80;//一旦被赋值,就无法改变了
		System.out.println(i);
	}
	 public final void eat () {
		System.out.println("吃饭");
	}
}
//class Man extends Person {
//	@Override
//	public void eat() {
//		System.out.println("吃的多");
//	}
//}
public class Demo1 {
	public static void main(String[] args) {
		final Person person = new Person();
		System.out.println("Person:" + person);
		//一旦使用final修饰person 对象引用 是一个固定的内存地址
		Person person1 = new Person();
		System.out.println("Person1:"+ person1);
		//person.name = "嘻嘻";
		//person = person1;//将person1赋值给了person对象
		System.out.println(person);
	}

}

17.15接口【重要】

意义:自身不具备的一些扩展的功能

1.语法格式:

interface 接口名字 {
	成员变量
	成员方法
}

如何实现?使用关键字implements实现接口

package com.qfedu.e_interface;

interface A {
	//接口下面的属性都是常量   常量是使用static 和final修饰的
	//只不过在接口中把 static和fianl省去了 常量的名字都要大写
	String NAME = "狗蛋";
	//在接口一般不写属性的!!!
	//成员方法  在接口中全部是抽象的方法  省略abstract
	public void eat ();
	public void sleep();
	
}
//无法实例化接口A ,咋办?新建一个类去实现(implements)接口
class TestA implements A {

	@Override
	public void eat() {
		// TODO Auto-generated method stub
		System.out.println("吃好饭");
	}

	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("睡好觉");
	}
	
}
public class Demo1 {
	public static void main(String[] args) {
		TestA testA = new TestA();
		testA.eat();
		testA.sleep();
		
		System.out.println(testA.NAME);
	}

}

注意事项:

1.使用关键字interface声明一个接口

2.接口中可以有属性,但是默认使用static和final修饰,被称为常量,名字大写(几乎不用)

3.接口下面全部都是抽象的方法,都没有方法体,默认省略了abstract,public修饰符也是默认的,也可以不写

4.jdk1.8后接口中是可以有默认(default)方法的,这个默认方法有方法体**【重点!!!】**

5.接口下没有构造方法,不能被实例化

6.可以用一个普通类去实现接口(implements),类似于继承,但有不同

7.必须在实现类中实现所有的抽象方法

8.一个普通类可以实现多个接口,使用逗号隔开,弥补了单继承的局限性

9.一个接口可以继承另一个接口(使用extends)

package com.qfedu.e_interface;

interface B2 {
	public void work();
}
interface B1 extends B2{
	public void smoking();
}

interface A1 {
	String NAME = "狗蛋";
	
	
	public void test();
	public void eat();
	public default void sleep () {
		System.out.println("睡觉睡得啥也不知道");
	}
}
class TestA1 implements A1, B1{

	@Override
	public void test() {
		// TODO Auto-generated method stub
		System.out.println("测试");
	}

	@Override
	public void eat() {
		// TODO Auto-generated method stub
		System.out.println("吃东西");
	}
	@Override
	public void sleep() {
		System.out.println("睡得什么都不会了");
	}

	@Override
	public void smoking() {
		// TODO Auto-generated method stub
		System.out.println("不要在整栋楼抽烟!!!");
	}

	@Override
	public void work() {
		// TODO Auto-generated method stub
		
	}
	
}
public class Demo2 {
	public static void main(String[] args) {
		TestA1 testA1 = new TestA1();
		testA1.eat();
		testA1.test();
		testA1.sleep();
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值