最近复习了一下Java基础,清晰了一些想当然和模糊的定义
关于继承
protected限定词
(以下简称protected):
- 一个类不与父类在同一个包,同时也不继承父类,那么父类的protected的变量和方法都无法访问。
- 一个类不与父类在同一个包,但继承于父类,那么子类可以访问父类protected静态的成员变量和成员方法,但无法访问父类实例的protected成员变量和成员方法。
- 一个类与父类在同一个包,子类无论继承与否,都可以访问父类静态和实例的protected成员变量和成员方法
用表格如图所示:访问的限定词是protected。
子类 | 同包 | 不同包 |
---|---|---|
继承 | 可访问静态和实例 | 可访问静态,但不可访问实例 |
不继承 | 可访问静态和实例 | 不可访问静态,也不可访问实例 |
代码示例:
包结构
- another
- AnotherOne 不同包但继承
- AnotherSon 不同包不继承
- father
- Son 同包继承
- One 同包不继承
- Father 父类
public class AnotherOne { //不同包 不继承
public static void main(String[] args) {
Father father = new Father();
// father.sayName(); //protected 变量和方法都无法访问。
// int iAge = Father.age;
}
}
public class AnotherSon extends Father { //不同包 继承
public static void main(String[] args) {//可以访问protected成员变量和成员方法
AnotherSon anotherSon = new AnotherSon();
String name = anotherSon.name;
anotherSon.sayName();
int iAge = Father.age;
Father father = new Father();
// father.sayName();//无法访问父类实例的protected成员
}
}
public class Father {
static protected int age = 50;
protected String name = "father";
protected void sayName(){
System.out.println("I am a father!");
}
}
public class One { //同包不继承
public void hello(Father father){
System.out.println(father.name);
}
public static void main(String[] args) {
Father father = new Father(); //可访问父类实例的protected成员
String string = father.name;
father.sayName();
int iAge = age; //也可访问父类静态的protected成员
}
}
public class Son extends Father { //同包 继承
private String name;
public static void main(String[] args) {
Father father = new Father(); //可访问从父类实例的protected成员变量和成员方法
String name = father.name;
father.sayName();
int iAge = age;
}
}
super
如果子类构造器没有调用super构造器,java默认调用父类的无参构造器。
换句话说,如果父类定义了有参构造器并且没有定义无参构造器,正好子类构造器也没有调用super构造器,那么就会报错。
多态变量
- Java中不存在对象对对象的赋值。 如何理解?
Object object1 = new Object();
Object object2 = new Object();
object2 = object1;
形式上像是 对象object1赋值给object2。
但其实是object2在内存地址指向了object1的地址。
而不是object2在内存地址中的值变成了object1的地址中的值。
验证代码如下:
public static void main(String[] args) {
Object object1 = new Object();
Object object2 = new Object();
System.out.println(object1);
System.out.println(object2);
object2 = object1;
System.out.println(object1);
System.out.println(object2);
}
输出结果:
java.lang.Object@629f0666
java.lang.Object@1bc6a36e
java.lang.Object@629f0666
java.lang.Object@629f0666
- 子类的对象可以赋值给父类的变量,而父类的对象不可以赋值给子类的变量。
Son Extends Father
Father father = new Son(); 正确
Son son = new father(); 错误
- 向上造型(向着父类造造型),造型转换是把该对象当作另一个种类型的对象来看待,对象没有被修改,而类型转换是修改了数据。
造型转换
Father father = (Father)new Son(); 正确
Son son = (Son) new father(); 可以通过编译,但是运行可能会报错
类型转换
float float1 = 2.0f;
int int1 = (int)float1;
多态
多态:通过一个变量调用一个函数,无需判断变量的类型。
如何理解?
对象调用方法,引用的是动态类型的方法,并非声明类型的方法。
public class Father {
void print(){
System.out.println("father");
}
public static void main(String[] args) {
List<Father> fatherList = new ArrayList<>();
fatherList.add(new Father());
fatherList.add(new Son1());
fatherList.add(new Son2());
fatherList.add(new Son2());
fatherList.add(new Son1());
for (Father father : fatherList) {
father.print();
明明调用的是Father.print()但是还是自动选择合适print方法。
这说明对象调用方法,引用的是动态类型的方法,并非声明类型的方法
}
}
}
class Son1 extends Father{
void print(){
System.out.println("Son1");
}
}
class Son2 extends Father{
void print(){
System.out.println("Son3");
}
}
class Son3 extends Father{
void print(){
System.out.println("Son3");
}
}
输出如下:
father
Son1
Son3
Son3
Son1
封装
- 封装并不是对类进行简单的setter/getter。
- 封装是用来降低类与类之间的耦合。
- 耦合:类和类之间的关系称作耦合,耦合越低越好,保持距离是形成良好代码的关键
可扩展性
只讲一种:
用接口来实现聚合,把细节隐藏在类内,今后类内如何实现与外部无关。