单例模式 继承 多态
单例模式有23种,但是她必须满足 一个类产生一个实例。
单例模式有以下特点:
(1)单例模式只有一个实例;
(2)单例类必须创建自己的唯一实例;
(3)单例类必须给所有其他对象提供这一实例;
懒汉式单例模式:
class MySinglecTon{
private static Object lock = new Object();
private static MySinglecTon singlecTon = null;
private MySinglecTon(){
System.out.println("MySinglecTon().init");
}
public static MySinglecTon getSinglecTon() {//提供一个全局访问点
if (singlecTon == null) {
synchronized (lock) {
if (singlecTon == null) {
singlecTon = new MySinglecTon();
}
}
}
/*3、if(sigleTon == null) {//第一个线程获取资源后
synchronized (lock) {//接着进行上锁,如果第一个线程的地址没有赋给第一个线程,人后第二个线程进来判断资源为空也可以进来,但是执行不了
sigleTon = new MySigleTon();//至少执行2遍
}
}*/
/*2、synchronized (lock) {//第一个线程进来之后上锁,
if(sigleTon == null) { //进来获取资源后,如果将地址没赋给第一个线程,那第二个线程无法进入,导致资源的浪费
sigleTon = new MySigleTon();
}
}*/
/*1、if(sigleTon == null) {//只适用于单线程
sigleTon = new MySigleTon();
}*/
return singlecTon;
}
public static void main(String[] args) {
MySinglecTon singlecTon = MySinglecTon.getSinglecTon();
System.out.println(singlecTon);
}
}
饿汉式单例模式:
class MySingleTon{
private static MySingleTon singleTon = new MySingleTon();
private MySingleTon(){
System.out.println("MySingleTon().init");
}
public static MySingleTon getSingleTon(){//提供一个全局访问点
return singleTon;
}
}
public class eh {
public static void main(String[] args) {
MySingleTon singleTon = MySingleTon.getSingleTon();
System.out.println(singleTon);
}
}
线程安全的单例模式:
线程安全 是否有竞态条件,就是临界区代码段,有代码段之后是否进行了原子性操作,原子性操作就是对其进行加锁处理。
静态内部类实现单例模式:
class MysingleTon2{
private MysingleTon2(){
}
private static class SingleTon{ //只有访问静态内部类的时候才会创建对象
public static MysingleTon2 a = new MysingleTon2();
}
public static MysingleTon2 getInstance(){
return SingleTon.a;
}
}
public class Demo3 {
public static void main(String[] args) {
MysingleTon2 Singleton2 = MysingleTon2.getInstance();
System.out.println(Singleton2 );
}
}
访问修饰限定符:
(public)基类的数据成员派生类的访问权限
继承:
派生类继承了基类出构造函数的所有属性。
super(); 调用基类的构造函数
super.data 访问基类的数据成员
super.fun(); 调用基类的成员方法
class Base{
protected int cf;
public Base(int cf){
System.out.println("Base,init()");
this.cf = cf;
}
static {
System.out.println("Base.static{}");
}
{
System.out.println("Base.instance{}");
}
}
class Derieve extends Base{
private int df;
public Derieve(int cd,int cg){
super(cd);
System.out.println("Derieve,init{}");
}
static {
System.out.println("Derieve.static{}");
}
{
System.out.println("Derieve.instance{}");
}
public void fun(int cd) {
System.out.println("Derieve.fun(int)");
}
}
重载(overload):函数名相同,函数列表不同 与返回值不同,同时在继承关系上也可以构成重载。
重写(override):也叫覆盖 ,函数名相同 参数列表不同,返回值相同, 但在一定条件下可以不同 ,(遵守了协变类型)。
class Base{
protected int cf;
public Base(int cf){
System.out.println("Base,init()");
this.cf = cf;
}
public void fun(){
System.out.println("Base.fun()");
}
}
class Derieve extends Base{
private int df;
public Derieve(int cd,int cg){
super(cd);
System.out.println("Derieve,init{}");
}
public void fun(){
System.out.println("Derieve.fun()");
}
public void fun1(int cd) {
System.out.println("Derieve.fun1(int)");
}
}
派生类构造函数的初始化顺序:
基类派生类静态块初始化 =》基类实例块构造初始化=》派生类实例块构造函数初始化
基类和派生类的赋值:
只能把派生类的值赋给基类(这也是多态的基础)
动多态:
class Base{
protected int cf;
public Base(int cf){
System.out.println("Base,init()");
this.cf = cf;
}
public void fun(){
System.out.println("Base.fun()");
}
public void fun1(){
System.out.println("Base.fun1()");
}
}
class Derieve extends Base{
private int df;
public Derieve(int cd,int cg){
super(cd);
System.out.println("Derieve,init{}");
}
public void fun(){
System.out.println("Derieve.fun()");
}
public void fun1(){
System.out.println("Derieve.fun1()");
}
}
public class jc {
public static void main(String[] args) {
Base base = new Derieve(111,222);
base.fun1();//静多态 编译的时候
base.fun();//动多态 运行的时候
}
}
基类产生的对象存放在堆上的方法表,在其方法区有当前class类的地址,当基类引用了派生类的对象时,其地址会被派生来的地址所覆盖,从而输出的为派生类的方法。