什么是继承
面向对象的三特性:封装、继承、多态
面向对象特征:继承
把多个类公共的部分提取出来,作为一个父类。
用继承的好处:
- 优化设计
- 方便修改代码
- 减少代码量
(重复代码可以不用写,直接放在父类中,到时候子类去调就行)
特点:
- 子类与父类是is - a关系。(子类 is a 父类)
- 其他类用extends关键字可以继承父类
- 可以继承所有的属性和方法
(私有的属性和方法不可见,不代表没有继承) - 被继承的方法就是自己的 不需要造父类对象
- 子类不能调用父类私有方法 ,只能继承可见的 ,虽然实际上都继承了。
- 私有的属性也不可见,但也继承了,要用需要使用getter。
(私有化的目的不让访问)
子类继承父类的什么?
继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包里
继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里
如何使用继承?
父类
[访问修饰符] class Pet {
//公共的属性和方法
}
子类(继承父类)
[访问修饰符] class Dog extends Pet { //继承关键字
//子类特有的属性和方法
}
继承是Java中实现代码重用的重要手段之一。
Java中只支持单(根)继承,即一个类只能有一个直接父类。
不能继承父类构造方法,但默认会调用父类构造。
这是Java里的规范。(也可以用super()来调用)
但也有一种说法所有子类默认的构造方法是从父类传递来的,
最终是Object。
理解继承 :
子类访问父类成员
-
访问父类构造方法
super(); //父类无参构造
super(name);//父类有参构造 -
访问父类属性
super.name; -
访问父类方法
super.print();
super关键字来访问父类的成员
- 使用super关键字,super代表父类对象
(1) this 代表本类对象
(2)在没有(同名属性、同名方法)冲突的情况下,this和super效果相同。
(3)this和super只有重名才有实际意义
(4)子类和父类都有同名属性,那么子类就会覆盖从父类继承的属性。
(5)正常情况,子类里用的是this ,除非你专门用super 来赋值
但父类对象拿不到 也没有意义
(6)父类的有参方法,子类不能直接调用,必须在子类用super才能调用
- 在子类构造方法中调用且必须是第一句
- 不可以访问父类中定义为private的属性和方法
- super只能出现在子类的方法和构造方法中
继承条件下的构造方法
public class Father {
public Father() {
System.out.println("爸爸在这里!");
}
}
public class Son extends Father{
public Son() {
System.out.println("儿子在这里!");
}
public static void main(String[] args) {
Son s1 = new Son();
//内存当中,先创建父类对象,再创建子类对象
}
}
结果为:
爸爸在这里!
儿子在这里!
-
继承的时候,创建子类对象必须先隐式创建父类对象。
-
只要父类有无参构造,创建子类时,会先执行父类无参。
父类没写构造方法,那就默认有个无参构造,子类都能执行。
(隐性创建,没有办法显式的去调用它)
子类构造不指定哪个父类构造器,那就是默认调用父类无参构造器。
- 父类如果有有参构造,最好不去掉无参构造。
子类有有参构造时(父类有有参构造和无参),执行的还是父类无参构造。
必须要有父类无参构造,不然子类就会报错。(没有父类哪来的子类)
- 如果父类只有有参构造,这时没有无参构造,
子类的构造方法会失效,除非子类用super显式调用父类有参构造。
(super(类型对应的值))
子类构造方法通过super显式调用父类的有参构造方法
(此时父类无参构造方法不会执行)
执行父类相应构造方法,而不执行父类无参构造方法
-
子类构造方法能通过this显式调用自身的其他构造方法。
-
子类的构造方法是建立在父类的构造方法上的。
当父类只有有参,子类啥也没有来造个对象,就会报错
父类必须要有无参,子类才能创建对象 -
不能同时调父类的有参和无参 ,只能选择一种方式生成。
注意点:
所有的构造方法都是来自于Object类 (隐式的可以不写)
Object类是所有类型的父类
子类可以继承父类的所有资源吗?
不能被使用的父类成员
- private成员
- 子类与父类不在同包, 使用默认访问权限的成员
- 构造方法
何时使用继承?
- 符合is-a关系的设计使用继承
- 继承是代码重用的一种方式
将子类共有的属性和行为放到父类中
单例模式:
要求某一个类只有一个对象。
(设计模式中的最简单的一种)
好处是 :(摘录)
- 实现了整个程序对唯一实例访问的控制。
- 因为单例要求程序只能有一个对象,
所以对于那些需要频繁创建和销毁的对象来说可以提高系统的性能,
并且可以节省内存空间。 - 可以全局访问。
- 允许可变数目的实例。
坏处是:(摘录)
- 不适用于变化频繁的对象。
- 符合的场景有限。
- 如果实例化的对象长时间不被利用,
系统会认为该对象是垃圾而被回收,可能会导致对象状态的丢失 - 可扩展性较差。
懒汉式:(更推荐)(拿时间换空间)
第一次调用这个方法的时候对象才会被创建。
(通俗地讲,只有我要你,你才会创建,节约内存空间)
好处:延迟对象的创建
public class Singleton {
private static Singleton s;//本类的静态对象(变量)
private Singleton() {}
//构造器私有化,不让外界随便造对象
//造一个static方法,通过类名.方法来在外界造对象
//在静态方法中,不能引用成员变量(即,没有static修饰的变量)。
//可以引用类变量(即,static修饰的变量)。
public synchronized static Singleton getInstance() {
if(s == null) {
s = new Singleton();
}
return s;
}
}
synchronized:同步锁 (保证线程安全)
在同一时间,只能有一个线程进入到里面,不然就会引起并发问题。
饿汉式:(拿空间换时间)
只要访问这个类型,第一时间会先创建对象,哪怕你没有调用任何东西,
下次调用的时候,你就不需要在判断,节省了运行时间。
坏处:对象加载时间过长
如果内容过多,全部调用,可能会浪费空间。
好处:饿汉式是线程安全的
public class Singleton2 {
private static Singleton2 s;
static {
s = new Singleton2();
}
public static Singleton2 getInstance() {
return s;
}
//返回出去
}
注意点:
不管创建多少个对象(外界),它们的地址都是一样。都是s这个对象,没区别。
只要这个地址被创建出来,你在外界无论用什么方法都没有办法改变它的地址。(除了本类)
题外话:
final 关键字:
- 只要加上final (final修饰的类)就不能被继承!!!
举例:string类就是final类 - final修饰的方法是不能被子类重写 但可以用反射!
- final修饰(成员)变量就是常量,不可被修改,不能再被赋值。
常量是指不能被修改的值,不是指数字
public static final共同修饰成员变量来表示常量,
常量的命名规则是:所有字母都大写,不同单词之间使用下划线连接。
如: public static final double PI = 3.14;
为什么static final 一般放一起使用呢?
static修饰属性的时候是静态的。 (从属于类)
即静态成员变量在类加载的时候就进行了创建,在整个程序时按序销毁。
当一个静态常量需要我们反复使用的时候,我们就需要使用这种方法。
初始化顺序:
public class People {
static {
System.out.println("我是people静态方法");
}
public People() {
System.out.println("我是people构造方法");
}
}
public class Student extends People{
static {
System.out.println("我是stu静态方法");
}
public Student() {
System.out.println("我是stu构造方法");
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student();
}
}
结果:
我是people静态方法
我是stu静态方法
我是people构造方法
我是stu构造方法
类加载的时候(Studnet student), 先执行static代码块,先父类再子类,
再创建对象的时候 (new studnet ) ,然后执行构造方法,先父类再子类。
类的初始化过程
- 加载class文件
- 堆中开辟空间
- 变量的默认初始化
- 变量的显示初始化
- 构造代码块初始化
- 构造方法初始化
开源 可以看源代码
工作时,class 文件给别人,Java文件是源文件,不方便被别人看到。
jvm 看的是class文件,只读字节码。
要打印的话,就不能用return,用void类型方法
----2021.08.07