20200925 王维
知识总结
1.封装
java中封装的实质就是将类的状态信息(成员变量)隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息(成员变量)的操作和访问
封装反映了事物相对的独立性,有效避免了外部错误对此对象的影响,并且能对对象使用者由于大意产生的错误操作起到预防作用。同样面向对象编程提倡对象之间实现松耦合关系(尽量减少对象之间的关联性,以降低他们之间的繁杂度和依赖性)
封装的好处在于隐藏类的实现细节,让使用者只能通过程序员规定的方法来访问数据,可以方便地加入存取控制符,来限制不合理的操作
1.1 封装的步骤
①修改属性的可见性
修改属性的访问修饰符,使得其他类的访问受限
②设置gettter/setter
方法
③设置属性的存取限制
可以在getter/setter
方法中进一步利用条件判断语句进行赋值限制,对属性设置合法性检查
1.2 包
java中包是一种访问控制的封装的机制,通过包来限制和制约类之间的访问关系,实质就是文件夹,包名一般是 公司域名去掉www后倒置 + 项目名 + 模块/功能
作用:
①存放类,包中能够存放类,易于找到和使用相应的类文件
②放置命名冲突:java中允许有同名类存在,但是不能在同一个包下。可以通过包来区分不同的类
③包允许在更广的范围内保护类、数据和方法。根据访问规则,包外的代码可能不能访问该类
1.3 访问修饰符
访问修饰符可以限制和制约类之间的访问。访问修饰符有四种(三个关键字)
public
:公开的/公共的
protected
:受保护的
缺省(Package-Access)
:包访问修饰符
private
:私有的
类访问修饰符
访问修饰符 | 同包 | 不同包 |
---|---|---|
public | √ | √ |
缺省(Package-Access)` | √ | × |
类成员访问修饰符
位置 | public | protected | 缺省(Package-Access) | private |
---|---|---|---|---|
同类 | √ | √ | √ | √ |
同包类 | √ | √ | √ | × |
不同包子类 | √ | √ | × | × |
不同包非子类 | √ | × | × | × |
访问权限从大到小 public --> protected --> 缺省 --> private
访问修饰符不能用于方法中声明变量或形式参数,因为方法中声明的变量或形式参数的作用域仅限于该方法,在方法外是不可见的,在其他类无法访问。
2.继承
继承使用extends
关键字
新类可以在不增加自身代码的情况下,通过从现有类中继承其属性和方法来实现充实自身内容,这种现象或行为就称为继承。此时新类称为子类/扩展诶=类,现有类称为父类/超类/基类。
继承可以解决编程中代码冗余的问题,是实现代码重用的重要手段之一。继承是软件可重用性的一种表现。
继承最基本的作用就是使得代码可以重用,增加软件的可扩展性
继承分为单继承和多继承,java中只支持单继承,也就是一个类只能有一个直接父类
继承表达的是 is a 关系, 子类 is a 父类。
2.1继承特点:
①可以继承public和protected和默认修饰符修饰的属性和方法,默认修饰符修饰的属性和方法只能在同包中继承。private修饰的属性和方法不能被继承。
②父类的构造方法不能被继承
③子类可以扩展属性和方法
④自诶可以重写(Override)父类的方法,不能重写构造方法
⑤提高了类之间的耦合性,继承破坏了封装,因为父类是对子类开放的,修改父类会导致所有子类的改变,因此继承一定程度上破坏了系统可扩展性。
2.2 重写
重写(Override) 一般发生在继承中,描述子类重写父类的方法。当子类从父类继承的方法不能满足子类的需求时,子类可以重写此方法(也叫覆盖),以符合子类的需求。
子类中有和父类中同名且同参(相同)的方法,称为方法的重写(覆盖)。@Override
注意:①如果返回值不是同一个类型会报错(编译时),但如果返回值的类型是父类的子类不会报错,因为子类 is a 父类,是同一个类型
② 不能重写父类中 final 修饰的方法,不能重新给 final 修饰的属性赋值。
方法重写条件:
①重写一定发生在继承中
②重写方法要与被重写的方法相同(方法名称,参数列表,返回值类型)
③重写方法的访问全向不能缩小
重写与重载区别:重载发生在同一个类中,多个方法名相同,参数个数、类型、顺序不同,与返回值无关。重写发生在继承关系中,方法名、参数列表、返回值都相同,方法体可以改变
2.3 final
final 修饰的类不能被继承, final 修饰的属性(字段)不可修改, final 修饰的方法不能被重写。 final 修饰变量称为常量,常量必须在赋初始值后才能使用,且不能更改
final 修饰对象,不可变的是变量对于对象的引用(地址),对象本身是可变的。
final 修饰自变量,将方法的参数设置为 final 类型,表示在方法中,此参数不能改变
2.4 子类和父类的关系
public class Person {
public Person() {
System.out.println("Person()");
}
}
public class Student extends Person{
public static void main(String[] args) {
new Student(); //Person()
}
}
通过以上代码发现,在子类进行实例化时,调用父类的构造方法。在子类的构造方法中要调用父类的构 造方法,而且是先调用父类构造在执行子类构造方法中的其他语句。即是要实例化子类就得先实例化父类。
当父类中有无参构造时,子类的构造方法可以不写调用父类构造方法(super();),java会自动在子类的第一行加上父类的无参构造方法,但是,如果父类没有无参构造,就需要我们手动在子类构造中调用父类的构造方法。
2.5 super
super([参数列表]) 是调用父类的构造方法,在调用构造方法时必须放到方法的第一行。
super 表示父类引用,super.属性 表示调用父类的属性, super.方法([参数列表]) 表示调用父类的方法。
特点:
①super只能出现在子类(实例方法,给实例属性赋值,实例初始化和构造函数)中
②super用于调用父类的成员(方法、属性)和构造方法
③ super([参数列表]) 在调用父类构造方法时,要写在构造方法代码的第一行
④ super 不能调用父类 private 修饰的属性和方法,不同包下的子类也不能调用父类缺省的属性和方法。
2.6 this和super
this | super | |
---|---|---|
意义 | 表示当前对象的引用,谁调用就是谁 | 表示父类的引用 |
类 | 每个类都有 this | 只能出现在子类中 |
方法 | 在成员方法中可以使用,在 static 方法不 能使用 | 在成员方法中可以使用,在 static 方法不 能使用 |
构造方法 | this([参数列表]) 可以调用构造方法,必 须放在构造方法的第一行 | super([参数列表]) 调用父类的构造,必 须放在构造方法的第一行 |
属性 | this.属性 表示本类中的属性,如果本类 中没有,就向上一级类查找 | super.属性 父类的属性 |
注意:在构造方法中不能同时使用this调用构造方法和super调用父类的构造方法,因为他们都必须放在构造方法的第一行。
2.7 遮蔽(shadowing)和隐藏(hiding)
遮蔽:有些声明可能在其作用域的一部分被相同名称的另一个声明遮蔽。
class Test {
static int x = 1;
public static void main(String[] args) {
int x = 0;
System.out.print("x=" + x);
System.out.println(", Test.x=" + Test.x);
}
}
隐藏:表示将被继承但由于子类中的声明而不被继承的成员
class Super{
int x = 10;
static int y = 20;
}
class Sub extends Super{
int x = 11;
static int y = 21;
public void test(){
System.out.println("this.x = " + this.x); // x in class Sub
System.out.println("super.x = " + super.x);// x in class Super
System.out.println("this.y = " + this.y); // y in class Sub
System.out.println("Sub.y = " + Sub.y); // y in class Sub
System.out.println("super.y = " + super.y); // y in class Super
System.out.println("Super.y =" + Super.y); // y in class Super
}
public static void main(String[] args) {
Sub sub = new Sub();
sub.test();
}
}
运行结果:
this.x = 11
super.x = 10
this.y = 21
Sub.y = 21
super.y = 20
Super.y =20
static 方法可以被继承,但是不会被重写
2.7 实例化对象执行顺序
package com.itlaobing.pm;
public class Demo{
public static void main(String[] args) {
int n = 10;
A a = new A();
// 5 2 4 6 1 3
/*
* 1.父类的 static初始化
* 2. 子类 static 初始化
* 3. 父类 实例初始化
* 4. 父类的构造方法
* 5. 子类实例初始化
* 6. 子类构造方法
*/
}
}
class B {
{
System.out.println("4");
}
static {
System.out.println("5");
}
B(){
System.out.println("6");
}
}
class A extends B{
{
System.out.println("1");
}
static {
System.out.println("2");
}
A(){
System.out.println("3");
}
}
学习总结
对于访问修饰符,对他的作用的理解有点模糊,在类外访问,通过实例对象打点调用,和继承他的子类访问的概念有混淆。还有通过this和super调用,概念理解不清晰。
近期评论