Java之旅__基础篇之继承,多态,抽象类,接口

一、面向对象三大特征之继承extends

1.继承:就是将子类共有的特性提取到父类中,让子类可以继承父类的的这种特性,产生的这种关系就是继承关系extends

2.继承的好处:

1)提高代码的复用性

2)提高了代码的维护性

3)继承是多态的前提条件

3.继承的特点:

1)Java语言中只支持单继承,不支持多继承

2)Java中不能多继承,但可以多级继承。如:子类继承父类,父类继承爷爷类,子类也就间接的继承了爷爷类

4.注意事项:

1)子类继承父类,继承父类的所有非私有化成员

本身私有的成员变量/成员方法只能在本类中访问,外界不能访问的!,但是间接通过公共的访问方法来访问,setXxx()方法和getXxx()方法

2)子类继承父类,不继承父类的构造方法,但可以通过super关键字来访问父类的构造方法

3)因为继承提高了代码的耦合性,所以不要为了使用部分功能而去使用继承

5)继承中的成员关系:

1)子类继承父类,如果子类中的成员变量名称和父类的成员变量名称不一致的情况:  分别访问 既可

2)如果子类中的成员变量名称和父类的成员变量名称一致的情况:先在自己的局部位置找,找到就使用,找不到就去子类的成员位置找,还没有,就去父类的成员位置找,再找不打就报错, 遵循一个:"就近原则"

class Fu{
	//成员变量
	public int num = 100 ;
	public void method() {
		int num = 20 ;
		System.out.println(num);
	}
	
}

class Zi extends Fu{
	//成员变量
	//public int num2 = 200 ;
	//public int num  = 50 ;
	
	//子类的成员方法
	public void show() {
		System.out.println(num);
	}
	
}
//测试类
public class Demo{
	public static void main(String[] args) {
		Zi z = new Zi() ;
		//子类成员变量名称和父类成员变量不一致的情况:
		System.out.println(z.num);
		System.out.println(z.num2);
		
		//子类成员变量名称和父类成员变量一致的情况:
		z.show();
	}
}

6.关于继承中构造方法的关系:
 1)子类是不能继承父类的构造方法的,但是通过super()来访问父类的构造方法
 2)在继承中,子类中所有的构造方法都默认访问父类的无参构造方法;
 相当于子类的所有构造方法的第一句话:隐藏了super();
问题: 为什么,创建子类对象的时候,先执行父类的无参构造方法?
 因为可能要用到父类中的数据,所以要先让父类中的数据进行初始化(构造方法),
 父类初始化完毕了,然后才执行子类的构造方法(子类数据初始化)---->分层初始化!
 super():如果在子类的构造方法显示给出了,必须写在第一句,否则可能出现父类初始化多次!(可以省略不写.)

class Fu2{
	
	public Fu2() {
		System.out.println("这是父类的无参构造方法");
	}
	
	
	public Fu2(String name) {
		System.out.println("这是父类的有参构造方法");
	}
}
//定义一个子类
class Zi2 extends Fu2{
	
	public Zi2() {
		super("随便给") ;//里面不给访问的父类无参,随便给访问的父类有参,匹配父类的形参类型就行
		System.out.println("这是子类的无参构造方法");
	}
	public Zi2(String name) {
		//this();
		super("随便给");
		System.out.println("这是子类的有参构造方法");
	}
}
//测试类
public class ExtendsDemo2 {
	public static void main(String[] args) {
		//创建子类对象
		Zi2 z = new Zi2() ;
	}
		
}

7.经典的猫狗案例(继承版)

public class Animal{

	//属性私有化
	private String name ;//姓名
	private int age ;//年龄
	private String color ;//颜色
	
	//无参构造方法:alt+shift+s-->c
	public Animal() {
		super();
	}
	
	//有参构造方法:all+shift+s--->o
	public Animal(String name, int age, String color) { //"tom",3,"黄色"
		super();
		this.name = name;   //将具体的局部变量值赋值给成员变量了
		this.age = age;
		this.color = color;
	}
	
	//公共访问方法:alt+shift+s--->r
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	
	//其他成员方法
	public void eat() {
		System.out.println("动物了都需要吃饭...");
	}
	public void sleep() {
		System.out.println("动物困了都需要休息...");
	}
	
	
	
}
//猫类
public class Cat extends Animal {
	
	//alt+shift+s---c:全部生成!
	public Cat() {
		super();
	}

	public Cat(String name, int age, String color) {
		super(name, age, color); //super(xxx)访问父类的有参构造
		//super("tom",3,"黄色") ;
	}
	
	//猫的特有功能
	public void catchMouse() {
		System.out.println("猫抓老鼠...");
	}

	
}
//狗类
public class Dog extends Animal {

	public Dog() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Dog(String name, int age, String color) {
		super(name, age, color);
	}
	
	//特有功能
	public void lookDoor() {
		System.out.println("看门...");
	}

	
}

二、面向对象三大特征之多态

1.多态:一个事物在不同时刻的体现。如:猫可以是猫,也可以看作动物;  水可以是固态,液态,气态

2.前提条件:

1)实现继承

2)方法重写

3)父类对象引用指向子类       父类名 对象名 = new 子类名() ; //称为"向上转型

3.优点:

1)提高了代码的复用性(由继承来保证)
2)  提高了代码的扩展性(由多态的来保证)

4.猫狗案例(多态版)

多态的弊端:不能访问子类的特有功能,两种方法解决:

1)创建具体的子类对象(更耗费内存,因为重新开辟了堆内存空间)

2)向下转型      Zi z =(Zi)f;前提条件有多态: Fu f =new Zi();

class Animal{
	public void eat() {
		System.out.println("动物需要吃饭");
	}
	public void sleep() {
		System.out.println("动物需要休息");
	}
}
//定义一个子类
class Dog extends Animal{
	
	public void eat() {
		System.out.println("狗吃狗粮");
	}
	public void sleep() {
		System.out.println("狗卧着睡觉");
	}
	
	//特有功能
	public void lookDoor() {
		System.out.println("狗可以看门...");
	}
}
//测试类
public class DuoTaiDemo4 {

	public static void main(String[] args) {
		//多态的格式:父类引用指向子类对象(向上转型)
		Animal3  a = new Dog3() ; 
		a.eat();
		a.sleep();
		//a.lookDoor() ;
		
		//方案1)创建子类的具体对象来访问子类的特有功能!
		/*Dog3 d = new Dog3() ;
		d.lookDoor();*/
		
		//向下转型: 
		
		Dog d = (Dog)a; 
		d.lookDoor();
		
	}
}

5.多态中的成员访问问题

Fu f = new Zi();

 1)成员变量: 编译看左边,运行看左边!
 2)成员方法:编译看左边,运行看右边!(方法重写)
 3)静态的成员方法:   编译看左,运行看左!(静态的算不上方法重写,跟类直接相关,随着类的加载而加载!)
 4)构造方法:存在继承关系(还是分层初始化)  先让父类初始化,然后在是子类初始化!

class Fu{
	public int num = 100 ;
	public void show() {
		System.out.println("show Fu");
	}
	public static void function() {
		System.out.println("function Fu");
	}
	
}
//子类
class  Zi extends Fu{
	public int num2 = 200 ;
	public int num = 50 ;
	
	public void show() {
		System.out.println("show Zi");
	}
	
	public static void function() {
		System.out.println("function Zi");
	}
}
//测试类
public class DuoTaiDemo {
	public static void main(String[] args) {
		Fu f = new Zi() ;
		System.out.println(f.num);  //100
		f.show();                    //show Zi
		f.function();               //function Fu
	}
}

6.一道多态综合练习题

//看程序,写结果

class A {
	public void show() {
		show2();
	}
	public void show2() {
		System.out.println("我");
	}
}
class B extends A {
	/*
	 * public void show() {
		show2();
	   }
	 * */
	public void show2() {
		System.out.println("爱"); //爱
	}
}
class C extends B {
	
	public void show() {
		super.show();
	}
	public void show2() {
		System.out.println("你");//你
	}
}
public class Test3 {
	public static void main(String[] args) {
		A a = new B();
		a.show();          
		B b = new C();
		b.show();
		//向下转型
		C c =(C)b;
		c.show();
	}
}
//结果是:  爱 你 你

三、抽象类(abstract)

1.概念:定义抽象类的原因就是没有具体的实例化对象,更加贴近现实,如:现实中没有动物这个东西,它是抽象的

故概念是在一个类中,如果该类中存在一个功能,仅仅方法声明,没有方法体(抽象方法),需要将该类定义抽象类.

2.特点:

 1) 如果一个类中有抽象方法,那么该类一定是抽象类; 如果一个类是抽象类,那么该类中不一定存在抽象方法;

 2)抽象类不能实例化(不能创建对象),所以要实例化就要创建子类对象,父类引用指向子类对象,通过子类实例化,

也即抽象类多态
3)抽象方法的格式:没有方法体的方法
 权限修饰符 abstract 返回值类型 方法名(形式参数) ;
 可以修饰类,可以修饰成员方法
4)抽象类 必须强制子类完成的事情!(将抽象类中所有的抽象方法重写)

abstract class Animal{//这个必须使用抽象来定义
	
	//具体的动物才具体的吃的功能,将吃的功能抽象(没有方法体)
	public abstract void eat() ;
	public abstract void sleep();
	
}

3.注意事项:

1)抽象类没有抽象方法也可以,意义是不能创建对象,抽象类中的一些功能的返回值可能就是该类本身!
  例如(日历类:Calendar它就是抽象类,里面的功能getInstance()非抽象方法,返回值就是该类本身)

2)abstract关键字 (定义成员方法的时候) 和final关键字冲突,和private关键字冲突和static关键字冲突,不能共存

四.接口interface

1.概念:体现的是事物的一种扩展性功能,也是一种定义的标准

2.注意事项:
   1)接口中只能定义抽象方法
   2)接口不能实例化,通过接口的子实现类来进行实例化!  接口多态! 实现关系(implements)

   3)接口的子实现类 是具体类,只有具体类才可以实例化

   4)接口可以多继承

//定义一个接口:动物跳高接口
interface AnimalJump{
	public abstract void jump() ;
}
//定义一个接口的子实现类
class CatJumpImpl implements AnimalJump{

	@Override
	public void jump() {
		System.out.println("猫可以跳高了...");
	}
	
}

//测试类
public class InterfaceDemo {

	public static void main(String[] args) {
		
//格式:接口名  对象名  =new 子实现类名();    接口多态!
		AnimalJump aj = new CatJumpImpl() ; 
		aj.jump();
	}
}

3.接口中的成员特点:
成员方法:  只能是抽象方法,存在默认的修饰符,public abstract
成员变量:  只能是常量.存在默认的修饰符:public static final
构造方法:  不存在构造方法!

4.抽象类与接口的区别:
    1)成员的区别 
        成员变量:
            抽象类:既可以定义常量,也可以定义变量
            接口:只能是常量,存在默认修饰符:public static final...
        成员方法:
            抽象类:既可以定义抽象方法,也可以定义非抽象方法
            接口:只能是抽象方法,存在默认的修饰符:public abstract..
        构造方法:
            抽象类:存在构造方法,无参/有参,对数据进行构造初始化(分层初始化)
            接口:没有构造方法
    2)关系的区别
            类与类之间
                    不管这个类是抽象类还是具体类,都继承关系(extends)
                    支持单继承,不支持多继承,可以多层继承
            类与接口之间
                    实现关系(implements)
                    一个类继承另一个类的同时可以实现多个接口!
            接口与接口之间
                    继承关系(extends)
                    支持单继承,以及多继承!
    
    3)设计理念的区别
        抽象类,----在抽象类多态中使用: 存在继承关系---- >体现的一种"is a"的关系
            举例:
                父类引用指向子类对象: Animal a = new Cat() ;
        接口:体现的一个事物的扩展功能(额外功能),本身不具备的功能 
                子实现类 实现(implements)接口 :存在实现关系
                体现的是一种"like a"的关系!
                部分猫经过学习--->产生一个"跳高的功能" (跳高猫很像猫)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值