java第9天----abstract,接口,多态

昨天知识点总结

  • 1.封装
    • 利用对成员变量的封装从微观上理解封装
    • 讲解set,get的编写方法
  • 2.继承
    • 继承的由来
    • 继承的代码实现
    • 继承的重写
    • 继承中的构造方法
  • 3.单例
    • 设计模式
    • 单例的分类
  • 4.final
    • final基本作用
    • final实例

修饰词abstract:抽象的

  • abstract:抽象的
  • 有两种:可以修饰类或方法
  • 抽象类,抽象方法
    • 抽象类:在继承当中,提取父类方法的时候,每个子类都有属于自己的具体实现方法,父类不能去决定各自的实现功能,父类就不管了
    • 所以父类中只写方法的声明,只有方法声明的方法成为抽象方法,拥有抽象方法的类是抽象类
    • 方法的声明:没有方法体的方法
  • abstract的注意点
    • 1.有抽象方法的一定是抽象类,抽象类里不一定有抽象方法
    • 2.继承了抽象类的子类,一定要实现父类的抽象方法,如果不实现就要将自己变成抽象类
    • 3.抽象类不能直接创建对象,必须通过子类实现,所以抽象类必须要有子类。
  • 比较抽象类和普通类
    • 普通类可以直接创建对象,抽象类不行
    • 抽象类可以有抽象方法,普通类没有
  • 比较private,static,final,判断他们是否可以与abstract同时使用
    • private:被private修饰的方法不可以被重写,但是被abstract修饰的必须要重写
    • static:static修饰的可以通过类名直接调用,但是被abstract修饰的类必须通过子类实现功能
    • final:被final修饰的类不能有子类,但是abstract修饰的类必须有子类
    • 都不能与abstract同时使用
	public static void main(String[] args) {
		//抽象类不能再直接创建对象
		//Person person = new Person();
		Student student = new Student();
		student.run();
	}
//抽象类---拥有抽象方法的一定是抽象类
abstract class Person{
	String name;
	//抽象方法-----相当于制定了一个规则
	abstract public void run();
}
/*
 * 两种方法处理继承了抽象类的子类
 * 1.将当前的子类变成抽象类-----不好,原因;抽象类不能直接创建对象,子类变成抽象类之后还是无法工作
 * 2.在子类中重写工作方法
 */
class Student extends Person{
	//重写抽象方法
	public void run() {}
}

接口

  • 接口:intrerface
  • 构成:interface 接口的名字{接口实现部分
    • 成员变量:–默认是public,static final修饰
    • 成员方法:–
  • }
  • 注意:一般接口中不写成员变量,只写方法,----制定规则,接口相当于规则类表(方法列表)
  • 接口起着作用的方式----让类去实现接口
    • 1.类与类之间的关系—继承 extends
    • 2.接口与类之间的关系----实现 implements
  • 注意点
    • 1.接口与父类可以同时存在吗
      • 可以的
    • 2.父类与接口的功能如何分类?
      • 答:一般父类中放的是主要功能,接口中放的是额外功能,作为父类的补充
    • 3.一个子类只能有一个父类,也只能有一个接口吗?
      • 不是,有一个父亲,因为java是单继承的,但是可以同时实现多个接口
    • 4.接口可以直接创建对象吗?
      • 不可以
    • 5.接口与接口之间可以有关系吗?有什么关系
      * 有,有继承关系,并且是多继承
    • 6.当一个类实现的接口中出现了相同的方法,子类实现的功能会不会混淆吗?
      • 不会,因为两个接口都只是方法的声明,方法在实现在子类中,方法的实现只有一个
  • 总结:作用:让Java从单继承间接的实现多继承,扩充了原来的功能,实现了对类功能的补充
  • 从jdk1.7往后的版本允许接口有方法的实现,但是方法必须是被static或者default修饰的.
interface Inter1{
	int age = 4;//默认是public,static final修饰,所以必须给一个值
	public void play();//默认是public,abstract修饰
}
interface Inter2{
	int age = 4;//默认是public,static final修饰,所以必须给一个值
	public void run();//默认是public,abstract修饰
}
interface Inter3 extends Inter1,Inter2{//接口之间是继承的关系,可以多继承
	
}
//创建Bird类实现了Inter1和Inter2接口,多个接口之间用,隔开
class Bird implements Inter1,Inter2{
	public void play() {
		System.out.println("play");
	}
	public void run(){
		System.out.println("reu");
	}
}
class Mouse implements Inter3{
	public void play() {
		System.out.println("play");
	}
	public void run(){
		System.out.println("reu");
	}
}
  • 接口的子类重写方法注意事项
    • 如果一个类实现两个接口,这两个接口同时有相同的抽象方法,在子类中只需要重写一次这个方法。
    • 如果一个类实现两个接口,这两个接口同时有相同的抽象方法,在子类中只需要重写一次这个方法。
    • 如果两个接口里的方法名相同都是default方法,里面的方法体不同,在子类中需要重写这个方法。
    • 如果两个接口中方法名参数都相同的方法,一个接口是抽象方法,另一个是default修饰有方法体。这时该子类也必须重写该方法。

多态

  • 一种事物的多种形态 狗 – 动物 – 生物
  • 学生 ==高等动物 – 动物 – 生物
  • 多态:用父类的引用指向子类的对象
  • 原因:
  • 一个程序运行的时候分成三个阶段:
    • 预编译:程序打开的时候,活已经干完了(预编译命令 #define)
    • 编译:从打开程序开始,到点击左上角的三角,之前的阶段-----只会识别等号前边的引用类型,不回去识别后面的对象
    • 运行:从点击三角开始-------这里才会去真正识别=后面的对象
  • 多态的前提:类与类之间一定要有继承的关系
  • 优点 :可以调高代码的扩展性,使用之前定义好的功能,后面直接拿来使用,而不应再去创建新的方法解释在Demo7
  • 解释在Demo1
  • 缺点:不能中直接调用子类特有的方法,只能调用父类有的方法
	public static void main(String[] args) {
		//使用继承--使用子类的引用工作
		Dog2 dog = new Dog2();
		dog.play();//调用父类的方法
		dog.show();//调用自己的方法
		Animal2 animal = new Dog2();
		animal.play();
		//animan.show();//调用方法的工作机制:1.首先animal了找到Dog对象,Dog对象在重灾区调用show方法
		//不能通过的原因:正在编译的时候识别得是引用类型,不识别对象,所以只能识别出animal特有的方法
		}
class Animal2{
	String name;
	public Animal2(String name) {
		super();
		this.name = name;
	}
	public Animal2() {
		super();
	}
	public void play() {
		System.out.println("play");
	}
	
}
class Dog2 extends Animal2{
	public Dog2(String name) {
		super(name);
	}
	public Dog2() {
		super();
	}
	public void show () {
		System.out.println("show-dog");
	}
}

向上转型和向下转型

  • 前提:这里一定是多态
  • 父类的类型比子类的高
  • 向上转型:相当于自动类型转化,由低类型到高类型
    • 注意:是将子类的引用转成父类的引用,但是只是将= 前边的转换,与=后面的无关
  • 向下转型:相当于强制类型转换,由高类型到低类型
    • 注意:是将父类的引用强制转换成子类的引用,
	public static void main(String[] args) {
		//向上转型
		Animal3 animal3 = new Dog3();
	
		//向下转型--为了调用子类特有方法
		Dog3 dog3 = (Dog3)animal3;
		dog3.show();//调用子类特有的方法
	
		//注意点:
		//1.这里不叫向上转型,这是错误,不能使用子类的引用指向父类的对象
		//Dog3 dog33 = new Animal3();
	
		//2.这里不是多态,所以不是向下转型,向下转型的前提是多态
		Animal3 animal33 = new Animal3();
		Dog3 dog33 = (Dog3)animal33; 
	}
}
class Animal3{
	String name;
	public Animal3(String name) {
		super();
		this.name = name;
	}
	public Animal3() {
		super();
	}
	public void play() {
		System.out.println("play");
	}
	
}
class Dog3 extends Animal3{
	public Dog3(String name) {
		super(name);
	}
	public Dog3() {
		super();
	}
	public void show () {
		System.out.println("show-dog");
	}
}
  • 应用
	public static void main(String[] args) {
		Dog4 dog4 = new Dog4();
		Cat4 cat3 = new Cat4();
		feedAnimal(dog4);
	}
	public static void feedAnimal(Animal4 animal4) {
		//animal4.eat();
		
		//容错处理:包容这块出错的代码,不让让影响后面正常代码的执行--------增加用户体验
		//intstanceof本身是一个运算符构成:对象 intstanceof 类,作用:确定前面的对象是否是后面类或子类的对象,返回值是:turn
		//不是:返回false
		//注意点
		//1.instanceceof前后必须有继承关系
		if (!(animal4 instanceof Dog4)) {
			System.out.println("传入的对象不是Dog4或子类的对象");
			System.exit(0);//退出程序
		}
	
		//向下转型
		animal4.eat();
		Dog4 dog4 = (Dog4)animal4;
		dog4.show();
	}
class Animal4{
	String name;
	public Animal4(String name) {
		super();
		this.name = name;
	}
	public Animal4() {
		super();
	}
	public void play() {
		System.out.println("play");
	}
	public void eat() {
		System.out.println("动物吃");
	}
}
class Dog4 extends Animal4{
	public Dog4(String name) {
		super(name);
	}
	public Dog4() {
		super();
	}
	public void show () {
		System.out.println("show-dog");
	}
	public void eat() {
		
		System.out.println("狗吃");
	}
}

class Cat4 extends Animal4{
	public Cat4(String name) {
		super(name);
	}
	public Cat4() {
		super();
	}
	public void show () {
		System.out.println("show-cat");
	}
	public void eat() {
		System.out.println("猫吃");
	}
}

成员在多态下的使用

  • 多态下
  • 当父类与子类定义了同名的属性:成员变量编译的时候看父类,运行的时候还是看父类
  • 成员方法:编译的时候看父类,运行的时候看子类
  • 静态的成员方法:编译运行都看父类
	public static void main(String[] args) {
		//继承中成员的使用
		Zi zi = new Zi();
		System.out.println(zi.age);//3,说明在继承下,以子类的优先
		Fu fu = new Zi();
		System.out.println(fu.age);//5
	}
class Fu{
	int age = 5;
	public void eat() {
		System.out.println("eat");
	}
	public void play() {
		System.out.println("play");
	}
}
class Zi extends Fu{
	int age = 3;
	int a = 3;
	public void show() {
		System.out.println("Zi-show");
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值