java多态继承

多态

方法重写

继承中的成员方法访问特点:
          子类继承父类,当成员方法名称不一致的时候,分别调用
          当成员方法名称一致的情况,首先在子类中有么有该方法,如果有,就调用;如果没有,就调用父类的成员方法;
 

方法重写:override:继承里面的技术
          当子类出现了和父类一模一样的方法的时候,子类的方法会重写(覆盖,复写)父类的方法,调用的子类的功能
  方法重载:overload:方法里面的
          在方法中,多个方法名相同,并且他的参数列表不同,与返回值无关
                  参数列表不同:
                      1)参数个数不同
                      2)参数类型不同     

class Phone{
	public void call() {
		System.out.println("手机可以打电话了...");
	}
}

//新手机
class NewPhone extends Phone{
	//@Override //重写
	public void call() {
		super.call();
		System.out.println("手机看天气预报了...");
	}
}

//测试类
public class ExtendsDemo2 {
	public static void main(String[] args) {
		
		//创建子类对象
		NewPhone np = new NewPhone() ;
		np.call();
	}
}

final 

在实际开发中,有些方法不能直接覆盖的,这对这种情况,不想让子类重写父类的方法,引出final关键字
         final:最终的,终态的,无法更改的!
     可以修饰类,变量,成员方法! 

final的用法:
          final可以修饰类,该类不能被继承!
          final可以修饰变量(可以成员变量,局部变量),这个变量此时一个常量
          final可以修饰成员方法,方法不能被重写
  
  常量的分类
          字面值值常量
          自定义常量    final 

抽象类

比如动物吃的功能,每个具体的动物吃的功能不一样,在当前类中只是给出一个方法声明(抽象的,不带方法体)
          在一个类中,给出一个抽象功能,就必须将这个类定义为抽象类!
  抽象类的格式
              abstract class 父类名(Animal){
              }
  抽象方法的格式:
            public abstract(必须写)  方法名() ;  //抽象方法
  
  注意:
              1)如果一个类中有抽象方法,那么这个类一定抽象类
              2)抽象类中一定有抽象方法吗? 还可以非抽象的
  
  抽象类的特点:
              1)抽象类不能直接实例化(不能直接创建对象)
             2)子类必须重写父类的抽象功能 
  抽象类的子类:
          1)抽象类的子类如果是抽象类呢? 没有任何意义,因为使用的就是通过具体类创建对象,具体类都抽象类,没意义!
  
          2)子类是具体类的话,对象的创建工作,由子类完成--->父类名  对象名 = new 子类名() ; 抽象类多态

抽象类成员的特点:
          成员变量:
              可以是变量,也可以是一个常量(自定义常量)
          构造方法:
              所有的构造方法都是给对象进行初始话:1)默认初始化 2)显示初始化
          成员方法:
              可以是抽象的方法,也可以非抽象的方法

多态

多态:某个事物在不同时刻体现出来的不同状态!
 *         水:        事物
 *         液态    气态   固态
 * 
 *         猫狗案例:
 *             创建一个猫类的对象            右-->左
 *             Cat cat = new Cat() ; //猫是猫
 *             Animal a = new Cat() ;//也是另外一种方式:猫是动物
 * 
 * 多态的前提条件:
 *         1)必须有继承关系
 *         2)必须方法重写
 *             猫狗案例:每个动物具体的吃的功能是不一样,必须有方法重写,将父类的功能覆盖掉!
 *         3)必须有父类引用指向子类对象        :向上转型
 *                 格式:
 *                     父类名  对象名  = new 子类名() ;
 * 
 * 多态中的成员访问特点
 *         1)成员变量的访问特点:
 *             编译看左,运行看左    (左:父类)
 *         2)成员方法(一般没有强调静态方法都是非静态的)的访问特点:
 *             编译看左,运行看右
 *         3)构造方法:作用:就是给对象进行初始化的
 *         4)静态的成员方法的访问特点:
 *             编译看左,运行看左(静态的成员方法算不上方法重写,因为静态的都和类有直接关系!)

多态的好处:
 *         1)提高代码的扩展性(由多态保证)
 *         2)提高代码的维护性(由继承关系)

//动物类
class Animal{
	public void eat() {
		System.out.println("动物饿了,都需要吃饭...");
	}
	
	public void sleep() {
		System.out.println("动物困了,都需要睡觉...");
	}
}

//猫类
class Cat extends 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("狗躺着睡觉...");
	}
}
//提供一些其他动物类的
//猪类
class Pig extends Animal{
	public void eat() {
		System.out.println("猪吃白菜...");
	}
	public void sleep() {
		System.out.println("猪卧着睡觉...");
	}
}
/动物工具类
class AnimalTool {
public static void useAnimal(Animal a) { //参数需要的是该类的对象   Animal a = new Cat() ;
		a.eat();
		a.sleep();
	}
}
//测试类
public class DuoTaiDemo2 {

	public static void main(String[] args){
		//喜欢猫
		Cat c1 = new Cat() ;
		c1.eat();
		c1.sleep();
		
		//很喜欢猫
		Cat c2 = new Cat ();
		c2.eat();
		c2.sleep();
		System.out.println("-----------------");
		Dog d1 = new Dog() ;
		Dog d2 = new Dog() ;
		d1.eat();
		d1.sleep();
		d2.eat();
		d2.sleep();
		System.out.println("--------------------");
		/**
		 * 上述面创建对象除了对象名不一样,其他方式都一样
		 * 改进:将eat,sleep封装到一个功能里面
		 */
		useCat(c1);
		useCat(c2);
		useDog(d1);
		useDog(d2);
		
		System.out.println("--------------------");
		/**
		 * 刚才这种方式也可以去实现,但是比较麻烦,首先提供提供动物类,并且还需提供useXXX方法,
		 * 不够好,改进,提供一个动物工具类AnimalTool,将useXXX()放入到这个类中,然后调用
		 */
		/*AnimalTool.useCat(c1);
		AnimalTool.useCat(c2);
		AnimalTool.useDog(d1);*/
		AnimalTool.useAnimal(c1);//Aniaml a = new Cat() ;
		AnimalTool.useAnimal(d1);//Animal a = new Dog() ;
		Pig p = new Pig() ;
		AnimalTool.useAnimal(p);
	}
	
	//使用该功能调用eat(),sleep()
	public static void useCat(Cat c) {//形式参数是引用类型--->需要该类的具体对象
		c.eat();
		c.sleep();
	}
	public static void useDog(Dog d) {
		d.eat();
		d.sleep();
	}
	
	//提供一些其他动物的同时,还需提供useXXx方法
}

  多态的弊端:
 *         不能访问子类特有功能

class Father{
	
	public void method() {
		System.out.println("method Father...");
	}
}

class Son extends Father{
	public void method() {
		System.out.println("method Son...");
	}
	
	public void function() {
		System.out.println("function Son... ");
		
	}
}

//测试类
public class DuotaiDemo3 {

	public static void main(String[] args) {
		//向上转型 :父类引用指向子类对象
		Father f = new Son() ;
		f.method();
//		f.function() ;  子类的功能
		
		//如何解决多态的弊端?
		//1)子类 对象名 = new 子类名() ;
		//第一种方式可以去访问子类的特有功能,但是不好的原因:从内角度来考虑,他不断在堆内存开辟空间,浪费空间
		System.out.println("---------");
//		Son s = new Son() ;  
//		s.function();
//		s.method();
		
		//2)向下转型:前提必须有向上转型
		//将父类的对象强制转换为子类的引用呢?// 可以
		Son s = (Son)f;
		s.function();
		s.method();
	}
}

最优秀的方式:使用向下转型:将父类对象强制转换为子类的引用
 *             格式:
 *                 子类名  子类对象名 = (子类名)父类的对象;

class Animal2 {
	public void eat() {
		System.out.println("吃");
	}
	
	public void sleep() {
		System.out.println("睡");
	}
}

class Cat2 extends Animal2{
	public void eat() {
		System.out.println("猫吃鱼");
	}
	
	public void sleep() {
		System.out.println("猫趴着睡觉");
	}
}

//狗类
class Dog2  extends Animal2{
	public void eat() {
		System.out.println("狗吃骨头");
	}
	
	public void sleep() {
		System.out.println("狗躺着着睡觉");
	}
}

//测试类
public class DuoTaiDemo4 {
	public static void main(String[] args) {
		
		//向上转型:父类引用指向子类对象
		//内存是猫
		Animal a = new Cat(); 
		
		//还原成猫
		Cat c = (Cat)a;
		
		//内存是狗
		a  = new Dog() ;
		//还原成狗
		Dog d = (Dog)a;
		
		Cat cc = (Cat)a;//语法符合
	}
}

Interface

接口:(开发过程中要遵循面向接口编程!)
 *         将一些额外(扩展)功能,暴露出来,只要哪些类实现了这个接口,就一定要取实现接口中的功能!
 *         
 *     格式:
 *         interface 接口名{
 *             
 *         }
 * 
 * 接口的实现类和接口之间是一种实现关系
 *         class 类名  implements(实现) 接口名{
 *         
 *         }
 * 接口的子实现类:
 *         1)如果接口的实现类是一个抽象类;没有意义,接口本身不能实例化,需要通过子实现类来进行实例化,如果子实现类
 * 都被抽象了,不能创建对象了,这种没意义!
 *         2)接口的实现类是具体类,接口名 对象名 = new 子实现类名() ; 接口多态(推荐方式:开发中这种方式最多)
 * 
 * 接口不能实例化(不能创建对象)
 * 
 * 实际开发中命名规则:
 *     实现类命名规则:接口名+impl :实现类

接口的成员特点:
 *         成员变量:
 *             存在默认的修饰符:    public static finla
 *         构造方法:接口中没有构造方法
 *         成员方法:
 *             默认的修饰符:public abstract

关系的区别:
 *     类与类的关系
 *             extends:继承关系     单继承,不能多继承,但是可以多层继承
 *     类与接口的关系:implements :实现关系 ,并且一个类继承另一个类的同时还能实现多个接口
 *     
 *     接口与接口的关系:
 *             extends关系:可以是单继承,可以是多继承的!
 * 
 * 
 * 任何类都需要继承自Object类,代表所有类的根类.

 

 

你可能感兴趣的:(java多态继承)