Java基础之类和对象、单例模式、继承

Java类和对象

一般的类只能是public或者default的,若是public的,类名必须和文件名一样。一般在一个文件只写一个类,故这个类一般是加上public。

内部类还可以是private和protected,一般私有化(private),因为只有当前这个类才需要。这样只有它的外部类可以直接访问。所以里面的数据也无所谓是public还是private或者default的。

public class Out {
    private int d = 10;
    public int add() {
      // 外部类不能直接访问内部类的数据,除非new出内部类对象,如下
      // Out.In abc = new Out().new In();
        a = 3; // false
        b = 5; // false
    }
  // 内部类
    private class In {
        private int a = 100;
        int b;
        public int c;
        public void add() {
            System.out.println(d); // true, 内部类却可以直接访问外部类的数据
        }
    }

    public static void main(String[] args) {
        Out bb = new Out();
        Out.In abc = new Out().new In();
        bb.d = 20; // 本类可以直接访问private,一般不这样,而是写个set函数,搭配get函数
        System.out.println(aa.a); // 100
        System.out.println(bb.d); // 被修改为20

    }
}
  • 匿名对象
new Abc().run(); // 调用一次后这个对象就销毁
new Abc().run(); // 这是另外一个Abc对象了
  • 关于private
    • private变量:封装数据,只给用户看方法。例如private String name不能随修改,但是提供setName()、getName()方法可调用,实现数据的封装,更安全。
    • private方法:不用用户调用的函数,完成一些内部实现的细节,就可以定义成private。例如选择排序算法写成一个方法,里面有交换两个数据的过程,封装成函数。这个函数不需给用户操作(用户只需用一个sort()就行),这个swap()就定义成private的。

单例设计模式

可以保证一个类在内存中的对象唯一性,需对过个程序使用同一配置信息对象时,就需要保证对象的唯一性,这时就需要单例

工具类中,未用到(访问)对象成员数据,则可不用创建对象。为了防止创建对象,可以将构造函数定义为private

如何保证对象的唯一性?

  1. 不允许其他程序用new创建该类对象,构造函数设为private
  2. 在该类创建一个唯一的类实例
  3. 对外提供一个方法使其他程序可以获取到这个唯一对象

单例设计步骤

  1. 私有化(private)该类的构造函数
  2. 通过new在本类汇总穿件一个本类对象
  3. 定义一个puiblic方法,将2中创建的对象返回

饿汉模式

// 饿汉式--不管用不用得到,先new出一个再说
public class SingleDemo {
    // private不能将这个实例暴露出去,只能通过getInstance()获取,另为何是static?
    private static SingleDemo s = new SingleDemo();
    private SingleDemo() {}
    // 供外界调用来获取这个对象
    public static SingleDemo getInstance() {
        return s;
    }
  // 只有本类中可以new对象并调用add
    public void add() {
        System.out.println("danli");
    }
    public static void main(String[] args) {
      // 本类可以new
        SingleDemo a = new SingleDemo();
        a.add();
    }
}

public class Test {
    public static void main(String[] args) {
      // fasle, 其他类中若用到这个单例,不能new
        SingleDemo aa = new SingleDemo();
      // true
      SingleDemo aa = SingleDemo.getInstance();
    }
}

懒汉模式

// 另外一种单例设计模式--懒汉模式--用到了才new,延时加载
public class SingleDemo {
    // 先设为空
    private static SingleDemo s;
    private SingleDemo() {}
    // 供外界调用来获取这个对象
    public static SingleDemo getInstance() {
      if (s == null)
        s = new SingleDemo();
        return s;
    }

Q:为何成员变量是static,方法也是static?

A:因为在其他类中,不允许new出新对象,故不能调用getInstance(),如果我们设成静态方法,就可以通过Single.getInstance()来获取而无需new对象,又静态方法里的数据也必须是static的。故这个SingleDemo对象也必须是static的。

Q:饿汉模式和懒汉模式的区别?
A:懒汉模式是延时加载的,用到了才new;在多线程时不能保证对象的唯一性,是线程不安全的。饿汉模式是随着类的加载,就new出这个对象,不管用不用得上,是线程安全的。

继承

Java一般是单继承,不能直接多继承 --> 因为多个父类可能有相同的成员,调用会导致二义性。

但是可以多层继承,如 A --> B -->C--> D,可以表示A继承自B,而B继承自C,以此类推。

  • 本类成员和局部变量之间用this区分
  • 子类、父类的成员同名时用super区分
  • 派生类也不能访问基类的private成员,但是确实是继承过来了,只是不能访问而已,可以调用父类的set、get函数来操作子类的private成员,对父类没影响。
  • 若成员是protected等权限更高的,则不用set、get就可直接访问该成员。
  • 父类与子类的该成员是相互独立的,子类改变它自己的成员,父类保持原样。
package Chap1;


public class Fu {
  // 父类的成员是私有的,子类继承过去了也不能直接访问
  
    private int age;
    private String name;
    public Fu(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class Zi extends Fu {
  // 特有的job,父不能访问
    private String job;
    Zi(int age, String name, String job) {
        super(age, name);
        this.job = job;
    }
    public String getJob() {
        return job;
    }
  
    public static void main(String[] args) {
        Zi aa = new Zi(23, "Zi","Study");
        Fu bb = new Fu(55, "Fu");
      // 改变子类不会影响父类
        aa.setAge(24);
        aa.setName("zi");
      // zi 24 Study
      // Fu 55
        System.out.println(aa.getName()+" "+aa.getAge() + " " + aa.getJob());
        System.out.println(bb.getName()+" "+bb.getAge());

    }
}
  • 子类隐式执行super(),new一个子对象时,先调用父类的构造函数,再执行子类的构造函数。
  • 默认的构造函数是无参的,有参数的构造函数会覆盖无参的。这时候需要显式使用super(args),且必须放在第一行,若不显式写super,则执行默认的super(),即无参的父类构造函数。
class Fu {
  // 构造函数
  Fu() {
    System.out.println("father");
  }
  // 带参的构造函数
   public Fu(int age, String name) {
        this.age = age;
        this.name = name;
    }
}

class Zi extends Fu {
  
  Zi() {
    private String job;
    // super() 会打印“father”
    // 无参数时是默认构造器,这句super()可以不写。父类的构造函数默认执行,先执行
    // 
    
  }
  
  Zi(int age, String name, String job) {
    // 若不写,会默认调用无参的super()打印father
        super(age, name);
        this.job = job;
    }
}
  • 类是public,构造函数也是public的。他们的修饰符是对应的。

一个对象的实例化过程

Person p = new Person();

  1. JVM读取Person.class文件,加载进内存;若有父类,会先加载父类。
  2. 在堆内存中开辟空间,分配地址。
  3. 在对象空间中,对对象的属性进行默认初始化,如int age = 0; String name = null;
  4. 显示初始化,如private int age = 9。若是子类,则会先调用父类的构造器。
  5. (子)类的 构造函数进行特定的初始化。如下程序中age变成100。
  6. 初始化后,将地址传递给引用变量。Person p <-- new Person();
package Test;
// 先打印9
// 再打印100

public class Demo {
    private int age = 9;
    {
        System.out.println(age);
    }
    Demo(int age) {
        this.age = age;
    }
    public static void main(String[] args) {
        Demo aa = new Demo(100);
        System.out.println(aa.age);
    }
}


by @sunhaiyu

2016.12.8

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容