2021-04-05

Day10 封装、继承,多态,this、super关键字等
一、
1.1面向对象的三大特征:
封装
继承
多态

	有了封装,才有继承,有了继承,才能说多态。

1.2 面向对象的首要特征:封装 。什么是封装?有什么用?
	现实生活中有很多现实的例子都是封装的,例如:
		手机,电视机,笔记本电脑,照相机,这些都是外部有一个坚硬的壳儿。
		封装起来,保护内部的部件。保证内部的部件是安全的。另外封装了之后,
		对于我们使用者来说,我们是看不见内部的复杂结构的,我们也不需要关心
		内部有多么复杂,我们只需要操作外部壳儿上的几个按钮就可以完成操作。

	那么封装,你觉得有什么用呢?
		封装的作用有两个:
			第一个作用:保证内部结构的安全。
			第二个作用:屏蔽复杂,暴露简单。
		
	在代码级别上,封装有什么用?
		一个类体当中的数据,假设封装之后,对于代码的调用人员来说,
		不需要关心代码的复杂实现,只需要通过一个简单的入口就可以访问了。
		另外,类体中安全级别较高的数据封装起来,外部人员不能随意访问,
		来保证数据的安全性。
	
1.3、怎么进行封装,代码怎么实现?
	第一步:属性私有化(使用private关键字进行修饰。)
	第二步:对外提供简单的操作入口。

二、
1、封装的代码实现两步:

  第一步:属性私有化

第二步:1个属性对外提供两个set和get方法。外部程序只能通过set方法修改,只能通过get方法读取,
可以在set方法中设立关卡来保证数据的安全性。

在强调一下:
	set和get方法都是实例方法,不能带static。
	不带static的方法称为实例方法,实例方法的调用必须先new对象。

	set和get方法写的时候有严格的规范要求:(大家要按照规矩来)
		set方法长这个样子:
			public void set+属性名首字母大写(1个参数){
				xxx = 1个参数;
			}
		get方法长这个样子:
			public 返回值类型 get+属性名首字母大写(无参){
				return xxx;
			}

2、static关键字
2.1、static修饰的统一都是静态的,都是类相关的,不需要new对象。直接采用“类名.”访问。
2.2、当一个属性是类级别的属性,所有对象的这个属性的值是一样的,建议定义为静态变量。
2.3、

三、

1、this
1.1、this是一个关键字,是一个引用,保存内存地址指向自身。
1.2、this可以使用在实例方法中,也可以使用在构造方法中。
1.3、this出现在实例方法中其实代表的是当前对象。
1.4、this不能使用在静态方法中。
1.5、this. 大部分情况下可以省略,但是用来区分局部变量和实例变量的时候不能省略。
1.6、this() 这种语法只能出现在构造方法第一行,表示当前构造方法调用本类其他的
构造方法,目的是代码复用。

2、总结所有的变量怎么访问,总结所有的方法怎么访问!!!!
总结一下到目前为止我们在一个类中都接触过什么了。

3、继承extends
3.1、什么是继承,有什么用?
继承:在现实世界当中也是存在的,例如:父亲很有钱,儿子不用努力也很有钱。
继承的作用:
基本作用:子类继承父类,代码可以得到复用。(这个不是重要的作用,是基本作用。)
主要(重要)作用:因为有了继承关系,才有了后期的方法覆盖和多态机制。

3.2、继承的相关特性
	① B类继承A类,则称A类为超类(superclass)、父类、基类,
	B类则称为子类(subclass)、派生类、扩展类。
		class A{}
		class B extends A{}
		我们平时聊天说的比较多的是:父类和子类。
		superclass 父类
		subclass 子类

	② java 中的继承只支持单继承,不支持多继承,C++中支持多继承,
	这也是 java 体现简单性的一点,换句话说,java 中不允许这样写代码:
		class B extends A,C{ } 这是错误的。

	③ 虽然 java 中不支持多继承,但有的时候会产生间接继承的效果,
	例如:class C extends B,class B extends A,也就是说,C 直接继承 B,
	其实 C 还间接继承 A。

	④ java 中规定,子类继承父类,除构造方法不能继承之外,剩下都可以继承。
	但是私有的属性无法在子类中直接访问。(父类中private修饰的不能在子类中
	直接访问。可以通过间接的手段来访问。)

	⑤ java 中的类没有显示的继承任何类,则默认继承 Object类,Object类是 
	java 语言提供的根类(老祖宗类),也就是说,一个对象与生俱来就有 
	Object类型中所有的特征。

	⑥ 继承也存在一些缺点,例如:CreditAccount 类继承 Account 类会导致它
	们之间的耦合度非常高,Account 类发生改变之后会马上影响到 CreditAccount 类

四、

1、继承extends

1.1、测试:子类继承父类之后,能使用子类对象调用父类方法吗?
	可以,因为子类继承了父类之后,这个方法就属于子类了。
	当然可以使用子类对象来调用。

1.2、在实际开发中,满足什么条件的时候,我可以使用继承呢?
	凡是采用“is a”能描述的,都可以继承。
	例如:
		Cat is a Animal:猫是一个动物
		Dog is a Animal:狗是一个动物
		CreditAccount is a Account:信用卡账户是一个银行账户
		....
	
	假设以后的开发中有一个A类,有一个B类,A类和B类确实也有重复的代码,
	那么他们两个之间就可以继承吗?不一定,还是要看一看它们之间是否能够
	使用is a来描述。

		class Customer{
			String name; // 名字
			// setter and getter
		}

		class Product{
			String name; // 名字
			// setter and getter
		}

		class Product extends Customer{
		
		}

		以上的继承就属于很失败的。因为:Product is a Customer,是有违伦理的。

1.3、任何一个类,没有显示继承任何类,默认继承Object,那么Object类当中有
哪些方法呢?老祖宗为我们提供了哪些方法?

	以后慢慢的大家一定要适应看JDK的源代码(多看看牛人写的程序自己才会变成牛人。)
	先模仿后超越。
	java为什么比较好学呢?
		是因为Java内置了一套庞大的类库,程序员不需要从0开始写代码,程序员可以
		基于这套庞大的类库进行“二次”开发。(开发速度较快,因为JDK内置的这套库
		实现了很多基础的功能。)

		例如:String是SUN编写的字符串类、System是SUN编写的系统类。
		这些类都可以拿来直接使用。
	
	JDK源代码在什么位置?
		C:\Program Files\Java\jdk-13.0.2\lib\src.zip
	
	你现在能看懂以下代码了吗?
		System.out.println("Hello World!");
		System.out 中,out后面没有小括号,说明out是变量名。
		另外System是一个类名,直接使用类名System.out,说明out是一个静态变量。
		System.out 返回一个对象,然后采用“对象.”的方式访问println()方法。
	
	我们研究了一下Object类当中有很多方法,大部分看不懂,其中有一个叫做toString()
	的,我们进行了测试,发现:
		System.out.println(引用);
		当直接输出一个“引用”的时候,println()方法会先自动调用“引用.toString()”,然后
		输出toString()方法的执行结果。

2、方法覆盖

2.1、什么时候考虑使用方法覆盖?
	父类中的方法无法满足子类的业务需求,子类有必要对继承过来的方法进行覆盖。

2.2、什么条件满足的时候构成方法覆盖?
	第一:有继承关系的两个类
	第二:具有相同方法名、返回值类型、形式参数列表
	第三:访问权限不能更低。
	第四:抛出异常不能更多。

2.3、关于Object类中toString()方法的覆盖?
	toString()方法存在的作用就是:将java对象转换成字符串形式。
	大多数的java类toString()方法都是需要覆盖的。因为Object类中提供的toString()
	方法输出的是一个java对象的内存地址。

	至于toString()方法具体怎么进行覆盖?
		格式可以自己定义,或者听需求的。(听项目要求的。)

2.4、方法重载和方法覆盖有什么区别?

	方法重载发生在同一个类当中。

	方法覆盖是发生在具有继承关系的父子类之间。

	方法重载是一个类中,方法名相同,参数列表不同。

	方法覆盖是具有继承关系的父子类,并且重写之后的方法必须和之前的方法一致:
		方法名一致、参数列表一致、返回值类型一致。

3、多态的基础语法

3.1、向上转型和向下转型的概念。

	向上转型:子--->父 (upcasting)
		又被称为自动类型转换:Animal a = new Cat();

	向下转型:父--->子 (downcasting)
		又被称为强制类型转换:Cat c = (Cat)a; 需要添加强制类型转换符。
		什么时候需要向下转型?
			需要调用或者执行子类对象中特有的方法。
			必须进行向下转型,才可以调用。
		向下转型有风险吗?
			容易出现ClassCastException(类型转换异常)
		怎么避免这个风险?
			instanceof运算符,可以在程序运行阶段动态的判断某个引用指向的对象
			是否为某一种类型。
			养成好习惯,向下转型之前一定要使用instanceof运算符进行判断。
	
	不管是向上转型还是向下转型,首先他们之间必须有继承关系,这样编译器就不会报错。

3.2、什么是多态。
	多种形态,多种状态,编译和运行有两个不同的状态。
	编译期叫做静态绑定。
	运行期叫做动态绑定。
	Animal a = new Cat();
	// 编译的时候编译器发现a的类型是Animal,所以编译器会去Animal类中找move()方法
	// 找到了,绑定,编译通过。但是运行的时候和底层堆内存当中的实际对象有关
	// 真正执行的时候会自动调用“堆内存中真实对象”的相关方法。
	a.move();

	多态的典型代码:父类型的引用指向子类型的对象。(java中允许这样写代码!!!)

3.3、什么时候必须进行向下转型?
	调用子类对象上特有的方法时。

day18课堂笔记

1、多态在开发中有什么作用?
非常重要:五颗星。。。。(多态你会天天用,到处用!!!!)

多态在开发中的作用是:
	降低程序的耦合度,提高程序的扩展力。

	public class Master{
		public void feed(Dog d){}
		public void feed(Cat c){}
	}
	以上的代码中表示:Master和Dog以及Cat的关系很紧密(耦合度高)。导致扩展力很差。

	public class Master{
		public void feed(Pet pet){
			pet.eat();
		}
	}
	以上的代表中表示:Master和Dog以及Cat的关系就脱离了,Master关注的是Pet类。
	这样Master和Dog以及Cat的耦合度就降低了,提高了软件的扩展性。

面向对象的三大特征:
	封装、继承、多态

	真的是一环扣一环。

	有了封装,有了这种整体的概念之后。
	对象和对象之间产生了继承。
	有了继承之后,才有了方法的覆盖和多态。

这里提到了一个软件开发原则:
	七大原则最基本的原则:OCP(对扩展开放,对修改关闭)
	目的是:降低程序耦合度,提高程序扩展力。
	面向抽象编程,不建议面向具体编程。

2、解释之前遗留的问题

私有方法无法覆盖。

方法覆盖只是针对于“实例方法”,“静态方法覆盖”没有意义。(这是因为方法覆盖通常和多态联合起来)

总结两句话:
	私有不能覆盖。
	静态不谈覆盖。

在方法覆盖中,关于方法的返回值类型。
	什么条件满足之后,会构成方法的覆盖呢?
		1、发生具有继承关系的两个类之间。
		2、父类中的方法和子类重写之后的方法:
			具有相同的方法名、相同的形式参数列表、相同的返回值类型。
	
	学习了多态机制之后:
		“相同的返回值类型”可以修改一下吗?
			对于返回值类型是基本数据类型来说,必须一致。
			对于返回值类型是引用数据类型来说,重写之后返回值类型可以变的更小(但意义不大,实际开发中没人这样写。)。

3、super关键字

super能出现在实例方法和构造方法中。

super的语法是:“super.”、“super()”

super不能使用在静态方法中。

super. 大部分情况下是可以省略的。

super.什么时候不能省略呢?
	父类和子类中有同名属性,或者说有同样的方法,
	想在子类中访问父类的,super. 不能省略。

super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中
的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。

super的使用:
	super.属性名				【访问父类的属性】
	super.方法名(实参)		【访问父类的方法】
	super(实参)					【调用父类的构造方法】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值