java:封装与继承
封装与继承
活动地址:CSDN21天学习挑战赛
封装
一、封装的概念
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互.
二、封装的好处
1、隐藏细节,方便用户操作
2、可以对数据进行验证,保证安全合理。
三、如何封装?
1、私有化属性
2、提供一个公共方法set,用于对属性的值进行修改
3、提供一个公共方法get,用于获取属性的值。
4、将构造器中的赋值改成调用set方法。(选)
属性是私有的,在其他类中不能直接进行使用,只能通过set方法进行更改,通过get方法进行调用
四、封装实例
继承
一、继承的概念
继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。
二、继承示意图
三、继承的基本语法
class 子类名 extends 父类名{
}
1、子类继承了父类的所有的方法和属性,但私有的方法和属性不能再子类中直接访问。要通过公共方法访问。(在父类将私有的方法和属性封装)
package fabandsub;
public class Base {
public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;
public void Base(){
System.out.println("base0.…");
}
public void test100(){
System.out.println("test100");
}
protected void test200(){
System.out.println("test200");
}
void test300(){
System.out.println("test300");
}
private void test400() {
System.out.println("test400");
}
public void test500(){//封装test400方法
test400();
}
}
public class Sub extends Base { //子类I
public Sub() {
System.out.println("sub().……");
}
public void sayOk() {
//我们发现父类的非private属性和方法
// 都可以访问
System.out.println(n1 +" "+ n2 +" "+ n3);
Base();
test100();
test200();
test300();
test500();//可以通过这种方式曲线访问
}
}
2、Object是所有类的父类,反之java的所有类都是object的子类
注:idea中ctel + h 可以提看类的继承关系
3、子类的构造器必须调用父类的构造器。
例如系统默认的无参构造器,在子类调用构造器时,会调用父类的无参构造器。
而如果父类的构造器是自定义的有参构造器,那必须在子类中调用父类的构造器。且必须在第一行调用
super(形参列表); 调用父类构造器,并输入参数
4、this和super不能共存。因为二者都要求放在第一行。
5、super会上溯至object(类的所有父类)
6、java是单继承机制,子类只能继承一个父类(直接继承)
7、不能滥用继承关系,一般认为:继承的父子必须直接满足:子类 is a 父类。
四、继承的本质
1、子类和父类间是一种索引关系,即对于子类来说,他有一个隐藏的属性为“父类”,继承事实上是对这一隐藏属性的赋值。加载时会先加载该属性,并先为该属性分配内存空间。
2、对象的创建:对象创建后,会为对象提供多个对象的栈,(同名的属性因为在不同的栈中还是会被创建完成)
2、同名属性的继承情况:
在访问一个属性时,会先访问当前类(子类),如果查找到就会返回,如果查找到的是私有的(不能使用)会返回并报错,如果没有则向上,查找父类;直到abject类。
package aandb;
class A{
String name;
A(){//A类中的A构造方法,同时输出”a“
System.out.println("a");
}
A(String name) {//A类中的A构造方法(有参),同时输出a name
System.out.println("a name");
}
}
class B extends A{
System name;
B(){ //B类中的无参构造器,同时输出b
this("abc");
//由于this,所以没有super。同时this还会调用B的所有构造器
System.out.println("b");
}
B(String name){
System.out.println("b name");
}
}
/
class xiaoyi {
public static void main(String[] args){
B b = new B();
}
}
执行分析如下:
* 当调用B的构造器时,实参列表内无参数,所以调用无参构造器
* 进入无参构造器B,执行this指令,
* this指令有参数,this指令顶掉super指令的同时,会调用相应的有参构造器,
* 进入有参构造器内,会先执行默认的super,调用父类A的无参构造器A,
* 无参构造器A会初输出“a",然后返回
* 返回后输出“b name”,并返回
* 返回后输出”b“,并返回,回到主函数
* 主函数结束。
练习:
编写Computer类:
包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息
编写PC子类,继承Computer类,
添加特有属性【品牌brand】
编写NotePad子类,继承Computer类,添加特有属性【color】
编写Test类,在main方法中创建PC和NotePad对象,分别给对象中特有的属性赋值,以及从Computer类继承的属性赋值,并使用方法并打印输出信息。
五、super
1、可以访问父类的属性(非私有)
super。属性名
什么意思呢?是否记得我们前边写的:2、对象的创建:对象创建后,会为对象提供多个对象的栈,(同名的属性因为在不同的栈中还是会被创建完成)因为我们不知道未来我们要命名的对象的名字是什么,所以采用super,代表“XXX的父类”. 属性,就像this代表当前类一样。
2、可以访问父类的方法(非私有):方法同上
3、访问父类的构造器(这点前边已经用过了):只能放在第一句,也只能用一句
super(形参列表);
4、为什么要有spuer呢?
super是java封装的代表,对于子类来说,父类的属性和方法只能用,不能修改,即使在实例化为对象以后也不能。一方面编程时增加了一定的工作量,另一方面整体上的规范化反而减少了工作量。
同时,当父子类中出现了同名属性或方法,可以通过super的方式来访问。父类的属性和方法,不需要改动父类的存储结构。
如果不出现重复名,那么无论哪个都一样。
有一个疑问:super如何向上跳过父类中的重名属性,访问爷爷的重名属性?
总结:无论是封装,继承还是之后的多态,本质上都是java增加代码复用性的办法。
更多推荐
所有评论(0)