面向对象知识点总结(二)

一、面向对象之继承

(1)继承:把原有类中的公共的代码抽取到一个新类中,原有类和新类使用extends关键字进行关联。新类称之为父类,原有类

称之为子类,子类会继承父类的所有属性和方法。但是子类只能使用父类对子类可见的属性和方法(权限设置)。

案例:

public class ExtendDemo {
	public static void main(String[] args) {
		Student stu = new Student();
		stu.eat();
	}
}

class Person{
	private int name ;
	private int age ;
	public Person() {
	}
	public Person(int name, int age) {
		this.name = name;
		this.age = age;
	}
	public void eat(){
		System.out.println("吃饭中...");
	}
	
	private void work(){
		System.out.println("工作中...");
	}
}

class Student extends Person{
	private int num;
	private int name ;
	private int age ;
	public Student() {
	}
	public Student(int num, int name, int age) {
		this.num = num;
		this.name = name;
		this.age = age;
	}
}

 子类Student可以调用父类中,可见(public)方法eat,而不可以调用work方法,因为work的权限为private。

(2)权限修饰符


 
 
本类同包类子类其他类
public可以可以可以可以
protected 可以可以可以不可以
default可以可以不可以(同包子类可以)不可以
private 可以不可以不可以不可以

(3)多重继承与多层继承

java中类是多层继承,而不是多继承。换句话说 Student 能继承Person类,Person类又可以继承Person1类。但是,它不能同时继承Person、Person1、、、、这样的目的是考虑到如果,使用多继承,继承的类中定义了同名的方法,子类就不知道调用哪种方法,容易导致方法歧义。故Java设计者在设计的时候,考虑到这一点,所以,Java继承类是单继承,Java的继承结构是树状的。

(4)super关键字

super关键字可以调用父类可见的方法和属性

super.eat();//调用父类可见的方法

super.height = height;//调用父类可见的属性

当创建子类对象时,会默认去调用父类的构造方法,即在子类的构造方法中调用“super()”,即使没有书写super(),也会有默认

的“super()”。前提父类有无参构造方法。如果super(参数列表),则表示调用父类的有参构造方法。

注意:

super():调用父类的无参构造,super()代码必须放在方法的有效代码的第一行

this():调用本类的构造方法,必须放在有效代码的第一行

所以,super()和this()不能共存

(5)重写

在父子类中出现了方法签名一致的非静态方法,就称之为重写(Override),或者称之为覆盖
重写的"两等两小一大"原则:

  1. 方法签名一致,即方法名和参数列表保持一致
  2. 如果父类方法的返回值类型是基本数据类型/void,那么子类中的方法的返回值类型必须和父类的返回值类型保持一致
  3. 子类重写的方法的权限修饰符,必须要比父类方法的权限修饰符范围更大或相等
  4. 如果父类方法的返回值类型是引用数据类型,那么子类方法的返回值类型要么和父类的返回值类型一致,要么是父类返回值类型的子类。
  5. 子类抛出的编译时异常小于等于父类方法抛出异常(运行时异常对于重写没有影响)

补充:父子类中出现了方法签名一致的静态方法,就称之为隐藏。此时,子类的方法不会覆盖父类的方法。子类的方法被隐藏了。

二、面向对象之多态

多态:事物的多种形态

编译时多态:方法的重载

运行时多态:方法的重写

(1)运行时多态-向上转型

public class PolyDemo {
	public static void main(String[] args) {
		//向上转型
		Pets p = new Dog();
		p.eat();
		//向下转型
		Dog dog = (Dog) p;
		dog.play();
	}
}

class Pets{
	public void eat(){
		System.out.println("宠物要吃饭");
	}
}
class Dog extends Pets{
	public void eat(){
		System.out.println("狗狗要吃饭");
	}
	public void play(){
		System.out.println("狗狗要玩耍");	
	}
}

结果:

狗狗要吃饭
狗狗要玩耍

分析:通过多态性,向上转型调用子类覆写的方法,然后向下转型,调用子类特有的方法。

向上转型  : 父类 名称 = new 子类();

向下转型  : 子类 名称 = (子类) 父类名称();

多态编译时只会检查“=”左边和右边是否有继承关系,并不会真的去检查右边的实际类型。但在真正运行代码时,会根据右边实际创建的对象来调用对应的方法。

补充:

public class PolyDemo {
	public static void main(String[] args) {
		//向上转型
		Pets p = new Dog();
		p.eat();
		//向下转型
		Cat cat = (Cat) p;
		cat.play();
	}
}

class Pets{
	public void eat(){
		System.out.println("宠物要吃饭");
	}
}
class Dog extends Pets{
	public void eat(){
		System.out.println("狗狗要吃饭");
	}
	public void play(){
		System.out.println("狗狗要玩耍");	
	}
}
class Cat extends Pets{
	public void eat(){
		System.out.println("猫猫要吃饭");
	}
	public void play(){
		System.out.println("猫摸要玩耍");	
	}
}

运行以上案例:会报“java.lang.ClassCastException”异常。

分析:因为编译的时候,只会检查左右两边是否具有继承关系,如果左右两边具有继承关系,那么就不会报编译错误。

在编译阶段,发现p的类型是Pets,Pets和Dog有继承关系,所以编译通过,实际运行过程中,发现p的实际类型是Dog,Dog不能转换为Cat,所以会报“java.lang.ClassCastException”异常。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值