Java学习笔记(七)Java的封装继承和多态

1. 封装:隐藏对象的属性和实现细节,仅对外公开接口。

(1)private(私有变量):只能被定义它的类访问。

(2)protected(受保护变量):可以被定义它的类及子孙类直接访问,也可以由同一包中的其他类直接访问。

(3)public(公共变量):可以被任何类进行访问。

(4)package:可以被定义它的类和同一个包中的其他类(包括派生子类)所访问.(包变量在声明时常常省略package关键字),在其他包中的子类则不能访问父类的包变量

/*
public class Singleton {
	//静态的,保留自身的引用
	private static Singleton test = new Singleton();
	
	//必须是私有的构造函数
	private Singleton(){
		
	}
	//公共的静态方法
	public static Singleton getInstance(){
		return test;
	}
}
*/
public class Singleton {
	//静态的,保留自身的引用
	private static Singleton test = null;
	private int size = 512;
	//必须是私有的构造函数
	private Singleton(){
		
	}
	//公共的静态方法
	public static Singleton getInstance(){
		if(test == null){
			test = new Singleton();
		}
		return test;
	}
	public int getSize() {
		return size;
	}
	public void setSize(int size) {
		this.size = size;
	}
	
	public static void main(String[] args) {
		Singleton[] singleInstance = new Singleton[5];
		//使用内存中的同一个实例,因此结果均为512
		for(int i=0;i<5;i++){
			singleInstance[i] = Singleton.getInstance();//静态方法直接可以类名.方法
			System.out.println(singleInstance[i].getSize());
		}
		singleInstance[4].setSize(1000);
		for(int i=0;i<5;i++){
			System.out.println(singleInstance[i].getSize());
		}
	}
}
运行结果为:

512
512
512
512
512
1000
1000
1000
1000
1000

2. 继承:

(1)复用其他对象的代码有两种方法:

①. 继承:是由子对象完全继承父对象的数据和操作,"is"的关系。

②. 包含:把一个对象作为另外一个对象的一部分,从而达到复用的目的,"has"的关系。

(2)继承的理解:

①. 继承是类实现可重用性和可扩充性的关键特征,在继承关系下类之间组成网状的层次结构。

②. 继承避免公用代码的重复开发,减少代码的冗余。

③. 通过继承增强一致性,从而减少模块间的接口和界面

(3)单继承(Java支持):子类只能有一个直接父类,多继承(Java不支持):子类可以有多个直接父类。

Java不支持类的多继承,但支持接口的多继承。继承通过关键字extends实现。

构建一个Person类:

public class Person {
	protected String name;
	protected char sex;
	protected int age;
	
	public Person(){
		super();//表示对它的直接父类的构造函数的使用
		System.out.println("父类的构造函数");
	}

	public Person(String name, char sex, int age) {
		//super();
		this.name = name;//this加“.”表示获取本类的使用
		this.sex = sex;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public char getSex() {
		return sex;
	}

	public void setSex(char sex) {
		this.sex = sex;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	//添加方法
	public String getDetails(){
		return "这个人是:"+this.name;
	}
}

构造一个继承Person的Student类:

public class Student extends Person{//新增添了两个变量
<span style="white-space:pre">	</span>protected int chinese,math;
	
	public Student(){
		super();//调用父类无参构造函数
		System.out.println("Student类构造函数");
	}
	
	public Student(String name, char sex,int age,int chinese,int math){
		//super(name,sex,age);
		super.name = name;	//通过super调用父类成员变量
		super.sex = sex;
		super.age = age;
		
		this.chinese = chinese;
		this.math = math;
	}
	
	public double average(){
		return (this.chinese+this.math)/2.0;
	}
	
	//方法覆盖
	public String getDetails(){
		return "这个人是:"+this.name+",平均分是:"+this.average();
	}
}


(4)变量隐藏:

在子类对父类的继承中,如果子类与父类的成员变量同名,此时成为子类隐藏(override)了父类的成员变量。子类若要引用父类的同名变量,要用super关键字做前缀加圆点操作符引用,即“super.变量名”。

(5)方法覆盖:

在子类中重写父类的方法,它们的名称,参数以及返回类型完全相同。通过改写方法体来完成不同的功能。注意子类方法不能缩小父类方法的访问权限 。

(6)super关键字:

如果子类调用父类的构造函数,则通过super()调用来实现。

如果子类调用父类的同名方法,则通过super.方法名()来实现。

(7)this关键字:this变量代表对象本身

当类中有两个同名变量,一个属于类的成员变量,而另一个属于某个特定的方法,使用this区分成员变量和局部变量,使用this简化构造函数的调用

引用自身对象的成员变量,引用自身对象的成员方法,调用自身的构造方法--this(参数)


3. Java多态

(1)静态多态:在编译时,就可以被系统识别,也称为静态联编,重载(overload)方法采用静态联编的方法实现方法重载,在一个类中定义多个同名的方法,但这些方法的参数列表必须不一样,即参数的个数不同,或参数类型不同,或参数顺序不同,注意返回类型不能用来区分重载

(2)动态多态:在编译时不能被系统识别,而是在 运行时才被系统识别,也称为动态联编, 覆盖(override)方法,抽象方法和接口采用动态联编的方法实现

class sup{//定义一个sup类
	public int x,y;
	sup(int a,int b){
		this.x = a;
		this.y = b;
	}
	
	public void  display(){
		int z = this.x+this.y;
		System.out.println("add="+z);
	}
}

class sub extends sup{//定义的sub类继承sup
	sub(int a,int b){
		super(a,b);//调用父类sup的构造函数
	}
	
	public void  display(){//方法覆盖
		int z = this.x * this.y;
		System.out.println("product="+z);
	}
}

//dispaly在编译时不能被系统识别,而是在运行时才能被识别到
public class ResultDemo extends sub{//ResultDemo继承sub类
	ResultDemo(int x,int y){
		super(x,y);//调用父类sub的构造函数
	}
	
	public static void main(String[] args) {
		sup num1 = new sup(7, 14);
		sub num2 = new sub(7, 14);
		ResultDemo num3 = new ResultDemo(7, 14);
		num1.display();
		num2.display();
		num3.display();
		
		//动态联编运行时会检查num1的内存是sub的实例还是sup的实例
		num1 = num2;
		num1.display();
		
		num1 = num3;
		num1.display();
	}
}

执行结果为:

add=21
product=98
product=98
product=98
product=98

(3)父类和子类对象的转换

①. 自动转换向上映射都是自动转换

②. 强制类型转换父类对象转换为子类对象


格式:instanceof 判断前面的对象是否为后面的类的实例

if(父类对象名 instanceof 子类名){

    子类对象名 = (子类名)父类对象名;

}else{

    …

}

class ASuper{
	String s = "calss:A";
}
class BSub extends ASuper{//继承关系
	String s = "class:B";	//变量隐藏
}
public class TypeV {
	public static void main(String[] args) {
		BSub b1,b3;
		ASuper a1,a2,a3;
		
		BSub b2 = new BSub();
		a1 = b2;//向上映射
		a2 = b2;//向上映射
		System.out.println(a1.s);
		System.out.println(a2.s);
		
		b1 = (BSub)a1;//向下映射,静态联编
		System.out.println(b1.s);
		
		a3 = new ASuper();
		//b3 = (BSub)a3;
		
		if(a3 instanceof BSub)
			b2 = (BSub)a3;
		else
			System.out.println("can not be transformed");
	}
}

运行结果 :

calss:A
calss:A
class:B
can not be transformed



  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mengrennwpu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值