面向对象高级

面向对象高级

继承,抽象类,接口,多态,内部类

继承

(java只有单继承和多重继承(爷爸儿),没有多继承)

格式:
	class 父类{
	}
	class 子类 extends 父类{
	}
  • 可以避免代码太多重复(比如人-姓名年龄,学生-姓名年龄)在这里插入图片描述

  • Stdent2 继承Person2 .

在这里插入图片描述

第一步:Student s 创建对象,进入栈空间
第二步:new Student(); ,读取Student 继承Person类
第三步:先创建Person类的空间,地址:0x123
第四步:创建Student类的空间。
第五步:Student类中自动有个super,指地址0x123
第六步:写s.setName("张三"),方法,程序先进入Student类里面看,如果没有这个方法就通过super去        父类Person里面看,如果有就调用,没有就报错。
第七步:super调用父类方法。

super:
	  1、super可以访问父类构造方法
	  2、super可以访问父类的属性
	  3、super可以访问父类的方法	  

class Student extends Person{
	public Student(){
		super("无名称",1); //调用父类中的双参构造方法
		super.sex = "男";// 调用属性,(属性不能是private)
		super.setName(); // 调用方法
	}
}

无法同时调用this,和super。因为都需要放在第一行。

重写(override)

 1、参数列表=必须完全=与被重写方法相同
 2、返回值类型=必须完全=与被重写方法的返回类型相同
 3、访问权限=不能=比父类中被重新的方法的访问权限更低
 4、父类的成员方法=只能=被其它的子类重写
 5、声明为=static=和=private=的方法不能被重写,但是=可以=再次声明

在这里插入图片描述

java重载(overload)和重写(override)的区别

1、发生的位置:
		重载:一个类中
		重写:子父类中
2、参数列表现在
		重载:必须不同的
		重写:必须相同的
3、返回值类型
		重载:与返回值类型无关
		重写:返回值类型必须一直
4、访问权限:
		重载:与访问权限无关
		重写:子类的方法权限必须不能小于父类的方法权限
5、异常处理:
		重载:与异常无关
		重写:异常范围可以更小,但是不能抛出新的异常

final关键字

final用于修饰属性、变量
	final修饰的局部变量,只能赋值一次(可以先声明后赋值)
	final修饰的成员属性,必须在声明的时候赋值/
final用于修饰类
	final修饰的类,不可以被继承
final用于修饰方法
	final修饰的方法,不可以被重写
全局变量:(public static final)



final修饰变量会变成常量
	final int a = 10;
	a = 20; //报错,无法再次进行赋值
	-----------------
	final int a;
	a = 10;
	a = 20;// 报错,不能赋值为20

抽象类 abstract

类所描述的行为,方法是模糊的
比如:
	人的类,人可以有子类,学生警察护士老师
	人可以说话,但是每个子类说话方式不一样。所以父类说话方法没办法==统一被子类共同运用==
	
	所以我们写不了父类中的say();方法,那我们便把父类写成抽象类(因为有不确定的东西)

抽象类原则

1、不能被实例化操作,及不能使用new

2、一个抽象类必须被子类所继承,被继承的子类(如果不是抽象类),则必须重写父类的抽象方法(将它变成确定方法),如果子类是抽象类,那么继续得找继承

public abstract class Person{
	public void sayHolle(){
	System.out.println("你好"); //如果有{},则不是抽象方法
	}
	public abstract void say();//如果没有{}修饰,则必须要添加abstract
}

实现类(抽象类,必须要有子类继承)
(子类也可以是抽象类,但是子类必须在找子类继承)

public class Student extends Person{
	//子类不是抽象类,那么必须重写父类中得抽象方法
	public void say(){
		System.out.println("我是学生");
	}
}


public class Nurse extends Person{
	public void say(){
		System.out.println("我是护士");
	}
}

在这里插入图片描述


抽象类常见问题

1、抽象类不能被实例化(new)
2、抽象类不能被final声明(因为必须要有子类)
3、抽象类有构造方法(JVM自己创建,但是我们不能自己创建)
	子类在对象实例化时候,流程是和普通类继承一样得,都是要先调用父类得构造方           法,之     后在调用子类自己得构造方法。
4、抽象类必须用public 或者procted修饰。
5、子类必须实现重写=所有=抽象方法,如果一个抽象方法没有被重写,则子类必须也为抽象类

在这里插入图片描述
在这里插入图片描述


接口(进阶要面向接口编程)

降低程序耦合性
利于维护扩展

接口和抽象类得差别:接口全是抽象方法(和全局常量),不能有具体实现得方法

interface 接口名称{
	全局常量:
	抽象方法():(不能有大括号{}),
		且方法自动添加public abstract,所以可以不用添加
}

接口可以多继承
class 子类 implements 父接口1 ,父接口2{
}


接口和抽象类得区别
	1、抽象类:被子类继承
	   接口: 被子类实现
	2、抽象类:可以声明抽象方法和非抽象方法
		接口:只能声明抽象方法
	3、抽象类:可以定义普通变量
		接口:定义得变量全是公共得静态常量
	4、抽象类:被继承使用,无多继承
		接口:使用实现来使用,可以多继承
	5、抽象类:可以有构造方法
		接口:不能有构造方法

多态

多态的体现:
	子父类:子类就是父类的一种心态
	重载:一个类中方法的多态性体现
	重写:子父类中方法的多态性体现


多态的使用:对象的类型转化
	向上转型:将子类实例变为父类实例:
		格式:父类 父类对象名称 = 子类实例;		
	向下转型:将父类实例变为子类实例:
		格式:子类 子类对象名称 = (子类)父类实例;

在这里插入图片描述

a是学生,b是护士
所以a也可以是人,b也可以是人。
人也可以是a,人也可以是b
但是a不可以是b

instanceof,判断传入的对象是此类型的那种形态(那个子类对象)
Public static void main(String[] args){
Nurse n = new Nurse();
say(n);
Student s = new Student();
say(s);
}

public static void say(Person p){
	if(p instanceof Student){ // 判断是否为学生类
		Student s =(Student)p;
		s.say();
	}else{
		System.out.println("必须传入学生心态,才可以执行");
	}
} 

Object类

  • Object 是所有类的父类(基类),如果一个类没有明确的继承某一个具体的类,则将默认继承Object类。

  • Object可以接受任意的引用数据类型

    toString 方法, equals方法


toString建议重写
	public String toString(){
		return "姓名:"+ this.name +" 年龄:"+this.age;
	}

equals方法
	Person p1 = new Person("张三",18);
	Person p2 = new Person("张三",18);
	System.out.println(p1 == p2);   //false (可以看成==是来判断地址是否相等,因为两个对													象,所以地址不等)

如果比较两对象用“= =”是比较地址,如果要比较两个地址块的内容的话,就得重写equals方法

public boolean equals(Object o){
	if(this == 0){   //如果传进来的o地址和this相等,那么就相等
		return true;
	}
	if(o == null){
		return false;//如果传进来的o地址为null,则不相等
	}
	if(o instanceof Person){  //对Person类的判断
		Person p2 = (Person)o; // o的类型是Person类或者多态形式,进行强转
		if(this.name.equals(p2.name) && this.age == p2.age){
			//如果名字和年龄相等,则判断为相等
			return true;
		}
	}
	return false;
}


快捷键 shift+alt+s,系统可以自动生成

内部类(少用)

定义:
	一个类里面在或者一个方法里面,在定义一个类
四种:
	1、成员内部类
			类似成员变量,成员方法
	2、局部内部类
			定义在方法里的类
	3、匿名内部类
	4、静态内部类

成员内部类

在这里插入图片描述

特点: 
成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态	成员)。
不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法

局部内部类

定义在方法中

在这里插入图片描述


匿名内部类(和匿名类一样,只用一次)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IcVHWsp5-16在这里插入图片描述

使用限制:

1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
2、匿名内部类中是不能定义构造函数的。
3、匿名内部类中不能存在任何的静态成员变量和静态方法。
4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
6、只能访问final型的局部变量
为什么只能访问final局部变量

(后续学习),文件生成问题.class文件

因为内部类会被单独的编写成一个字节码文件,为了保证单独的字节码文件使用的变量和外面的是一致的,所以一定要用final进行限制不能修改


静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。
==静态内部类是不需要依赖于外部类对象的==,这点和类的静态成员属性有点类似,==并且它不能使用外部类的非static成员变量或者方法.==(因为静态保存在方法区,加载的比非静态的快)


包装类

可变参数

public static void main(String[] args){
						//以数组形式
	System.out.Println(sum(1,2,3,4,5)); // 结果15
}



public static int sum(int... nums){
	//可变参数,调用的时候可以传0-n个参数
	//参数在方法内部 , 以数组的形式来接收
	int a =0;
	for(int i=0;i<nums.length;i++){
		n += nums[i];//累加
	}
	return n;
}
注意:

方法区,加载的比非静态的快)



包装类

可变参数

public static void main(String[] args){
						//以数组形式
	System.out.Println(sum(1,2,3,4,5)); // 结果15
}



public static int sum(int... nums){
	//可变参数,调用的时候可以传0-n个参数
	//参数在方法内部 , 以数组的形式来接收
	int a =0;
	for(int i=0;i<nums.length;i++){
		n += nums[i];//累加
	}
	return n;
}
注意:
	可变参数只能出现在参数列表的最后。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值