java—06 继承 + 多态

本文介绍了Java中的继承概念,包括private关键字的影响、super的使用和this()构造器。此外,详细讨论了Object类作为所有类的基础,并指出单继承的特点。接着,重点讲述了多态的原理,包括方法重写、多态的好处及其成员访问特性。强调了继承是多态的前提,区分了编译时多态和运行时多态,并提到了类型转换异常和实现多态的机制。
摘要由CSDN通过智能技术生成

一、继承

1、private 小坑过

父类私有的方法,子类无法继承。但是父类私有的成员属性,子类是继承了的,通过公开的方法区访问。

public class ExtendsTest {

	public static void main(String[] args) {
		
		Dog dog = new Dog();
		dog.run();
	}
}
------------------------------------------------
public class Animal{
	void run() { 	
	// private void run() { 
	//报错:The method run() from the type Animal is never used locally
	
		System.out.println("running");
	}
}
class Dog extends Animal{
	
}

2、super是什么东西?

super()的用法:
1、在构造方法中只能出现一次,且是第一条语句
2super()只能用在构造方法中,其他地方不行。
super1、可以在成员方法中使用,可以通过super直接访问子类继承的父类的方法。静态的方法也是可以使用super访问的,但super不代表类名。
2super是可以省略的,但是在一种情况下,不能省略:
当父类和子类中拥有同样的方法时,要区分子类和父类中的方法,如果是子类的,this.方法(),这个this是可以省略的。如果是父类的方法,super.方法()super不能省略。
3、对于静态方法来讲,它是类级别的,与thissuper无关。不能用this去掉静态的方法,因为静态方法中没有this这个参数。super是可以调用静态方法的,但是它只是代表了父类的名字。


public class ExtendsTest {

	public static void main(String[] args) {
		
		Dog dog = new Dog(18,"小牛");
		dog.run();
           
	}
}
----------------------------------
/*我是父类的无参构造
父类得work
sleep!!!
eat
我是子类的有参构造
running
*/
----------------------------------
public class Animal{
	private int age;
	private String name;
	
	public Animal() {
		System.out.println("我是父类的无参构造");
	}
	public Animal (int age,String name) {
		this.age = age;
		this.name = name;
		System.out.println("父类有参构造");
	}
	void run() {
		System.out.println("running");
	}
	public void work() {
		System.out.println("父类得work");
		sleep();
		eat();
	}
	public static void eat() {
		System.out.println("eat");
	}
	private void sleep() {
		System.out.println("sleep!!!");
	}
}
class Dog extends Animal{
	public Dog() {
		
		System.out.println("我是子类的无参构造");
		
	}
	public Dog(int age, String name) {
		//work(); 子类的work方法,this.方法(),这个this是可以省略的
		super.work(); // super.方法()不能省略。
		System.out.println("我是子类的有参构造");
		
	}
}

3、this( )

this()
它代表的是当前的构造方法,只能在构造方法中用。它的作用是一个构造方法调用另一个构造的时候使用。

无参构造里的this.name = "小黑" 没有赋值
public class User 
{

	private int id;
	private String name;

	public User() {
        super();
		// this(0, "用户");  这样调用会很常见,尤其是在源码中。
		this.name = "小黑";
	}

	public User(int id, String name) {
		// this(); 这样调用意义不大
		this.id = id;
		this.name = name;
	}
	public static void main(String[] args) 
	{
		User user = new User(1,"小牛");
		System.out.println(user);
	}

	public String toString() {
		return "id= " + id + ", " + "name= " + name;
	}
}
id= 1, name= 小牛

二、Object类

object类是所有类的基类,java中只支持单继承,所以说Object类是最高层的父类。
省略了继承Object类的语法是extends Object。

public class Test {
	private String name;
	
	public Test() {
		
	}	
	public Test(String name) {
		this.name = name;
	}
	
	public static void main(String[] args) {
		Test test = new Test();
        System.out.println(test.toString());
	}

}
Test@372f7a8d

Test直接调用了toString()方法,一定是从 Object父类中来的。
    
 Object.java源码中的toString()方法:
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

三、多态

1、方法的重写

方法的重写发生的条件:

1、方法名、参数列表、参数位置、返回值类型一定要相同(有继承关系的引用进行自动类型转换不会报错)
2、方法的权限,重写只能更高,不能更低,也就是说public修饰的方法,重写的时候不能低于public权限,否则报错。
3private修饰的方法不能被重写
4、重写后的方法抛出的异常不能更多,只能更少
5、一定要有继承关系,才有重写的概念。

2、多态的好处

OCP: open close principle
23种设计模式中的七大原则中著名的开闭原则
开:对扩展开放
闭:对修改关闭
意思就是:在扩展功能的,增加这功能的时候,支持程序扩展新的功能,但是不要去更改程序中原有的代码
因为:原有的代码已经能够正常的运转,如果你增加功能的时候,修改了原有的代码逻辑,在原有的代码基础上增加了很多代码,就有可能造成更多的bug。这样的话破坏了软件的稳定性。扩展功能,最好的方式是,要求不更改原有的代码,但又能够扩展功能。这是开闭原则。也就是说把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

只修改方法的实现,不必修改方法的声明

3、认识多态

继承是多态产生的前提条件!!!

多态中成员访问特点:

  • 成员变量:编译看左边,执行看左边

  • 成员方法:编译看左边,执行看右边

  • 成员方法有重写,但是成员变量中没有

编译时的类型由声明该变量时使用的类型决定,运行时的类型由实际赋给变量的对象决定。
如果编译时类型和运行时类型不同,就出现多态。
分类:
编译时多态:方法重载
运行时多态:方法覆写

父类型引用指向子类型对象

Animal a = new Dog();这也叫做自动类型转换。
//Dog dog = new Animal; // X,子类型的引用指向父类型的对象
package Hello;

public class hello {
    public static void main(String[] args) {
        System.out.println("hello!");
        Zoo p = new Zoo();//管理员p

        Animal a = new Animal();
        p.feed(a);
       /* 管理员正在给 Hello.Animal@3941a79c 喂食
        我是动物,我在吃东西!*/

        Animal d = new Dog();
        p.feed(d);
        /*管理员正在给 Hello.Dog@4fca772d 喂食
        小狗正在吃骨头*/

        Animal c = new Cat();
        p.feed(c);
        /*管理员正在给 Hello.Cat@3d494fbf 喂食
        猫想要吃鱼*/

        Object obj = new Cat();
//        obj.eat(); 不可以,因为父类中没有eat方法,子类eat()方法重写变得更加强大
     
        
    }
}

class Animal{
//    private String name;
//    private String type;

    public Animal(){}
//    public Animal(String name, String type) {
//        this.name = name;
//        this.type = type;
//    }

    public void eat() {
        System.out.println("我是动物,我在吃东西!");
    }
}
class Dog extends Animal {

    public void eat() {
        System.out.println("小狗正在吃骨头");
    }

    public void gateGard() {
        System.out.println("小狗看门");
    }
}
class Cat extends Animal {
    public void eat() {
        System.out.println("猫想要吃鱼");

    }
}
class Zoo {
    /*
        public void feed(Dog dog) {
            System.out.println("管理员正在给 " + dog + " 喂食");
            dog.eat();
        }
        public void feed(Cat cat) {
            System.out.println("管理员正在给 " + cat + " 喂食");
            cat.eat();
        }
    */
    public void feed(Animal animal) {
        System.out.println("管理员正在给 " + animal + " 喂食");
        animal.eat();
    }
}

类型转换异常:ClassCastException



       //报错:Exception in thread "main" java.lang.ClassCastException:
        Dog xn = (Dog) a; //强制类型转换
        xn.gateGard();

Exception in thread "main" java.lang.ClassCastException:
class Zoo {
	public void feed(Animal animal) {
		System.out.println("管理员正在给 " + animal + " 喂食");
		Dog dog = (Dog) animal;
		// 编译时是通过的,运行时抛出异常ClassCastException
		dog.eat();
	}
}

避免类型转换异常:instanceof
语法:
    (引用 instanceof 类型) 结果为boolean
为什么要强制类型转换,我们已经说过了,就是要用多态机制,同时子类对象又要访问自己特有的属性和方法的时候,就要使用强制类型转换。
    强制类型转换的前提是,要有继承关系。
    
class Zoo {

	public void feed(Animal animal) {
		System.out.println("管理员正在给 " + animal + " 喂食");
      // 解决ClassCastException的办法
		if(animal instanceof Dog) {
			Dog dog = (Dog) animal;
			dog.eat();
			dog.gateGard();
		} 
		else if(animal instanceof Cat) {
			Cat cat = (Cat) animal;
			cat.eat();
			cat.catchMouse();
		} 
		else
		{
			animal.eat();
		}
	}
}

实现多态的机制:
父类的引用变量可以指向子类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的真正实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值