JAVA面向对象

一、类与对象的关系

  • 类 抽象的概念

  • 对象 看得见摸得着的具体实体
    类实例化后得到对象

  • 创建宠物猫类

package com.alan.animal;
/**
 * 宠物猫类
 * @author alan
 *
 */
public class Cat {

    //属性:昵称、年龄、体重、品种
    
    String name; //昵称 String 默认值null
    int month;   //年龄  int 默认值为 0
    double weight;  //体重 double 默认值为0.0
    String species; //品种
    
    
    //方法:跑动、吃东西
    //跑动的方法
    public void run() {
        System.out.println("小猫快跑");
    }
    //对跑动的方法进行重载
    public void run(String name) {
        System.out.println(name+"快跑");
    }
    //吃东西的方法
    public void eat() {
        System.out.println("小猫吃鱼");     
    }

}

  • 宠物猫类测试
package com.alan.animal;

public class CatTest {

    public static void main(String[] args) {

        //对象实例化
        Cat one = new Cat();
        
        //测试 调用方法
        one.eat();
        one.run();
        one.name = "花花";
        //在类没有初始化的情况下,构造函数对其进行默认的赋值 String 为null ,int 为0,double为0.0
        System.out.println("name="+one.name);
        System.out.println("species="+one.species);
        System.out.println("month="+one.month);
        System.out.println("weight="+one.weight);
        one.run(one.name);
        
    }

}

单一责任原则

  • 一个类只负责一个功能,如果一个类功能太多则耦合性过高,复用的可能性越低。

实例化对象

分为两个部分:

  • 声明对象 Cat one 在栈中开辟一块空间,但是没有赋值为null
  • 实例化对象 new cat(); 在堆里面开辟的一块空间
    Cat one = new cat(); // 将堆空间中的地址赋值给栈,栈为指向堆的引用
    image.png

构造方法(构造函数)

在new的时候构造方法会被调用,不能被对象单独调用
1、构造方法与类同名且没有返回值。
2、只能在对象实例化的时候调用。
3、当没有指定构造方法时,系统会自动添加无参的构造方法。
4、就近原则,如果使用name=name赋值,会优先选择同一个作用域,进行赋值,所以要使用不同名字,或者用this.name=name 进行赋值。


this关键字

  • 代表当前对象的属性或者方法,例如this.name表示当前这个class的属性。


    image.png

    image.png

this与创建的对象具有相同的ID值,说明this调用的就是当前的对象
this();可以调用无参构造方法,但是一定是在其他构造方法的第一行。
其他的方法不能调用构造函数。

二、Java封装

将类的某些信息隐藏在类内部,不允许外部程序直接访问。


image.png
  • 只有get方法 是只读属性
  • 只有set方法 是只写属性

创建包

同一个包中不允许出现相同文件名的Cat,引用同名的

package com.alan.test;

import com.alan.animal.Cat; 
import com.alan.mechanics.*; //通过.*直接加载到直接的类,不能使用com.alan.*这种方式

public class Test {

    public static void main(String[] args) {
        
        com.alan.mechanics.Cat one = new com.alan.mechanics.Cat(); //直接导入的是animal中的Cat,如果需要用mechanics中的需要在代码中加入com等具体的包路径
//      System.out.println("调用成功!");
    }

}

static关键字

//static 静态 静态成员 类成员 ,所有对象都使用一块内存空间,所以所有的实例化对象,static修饰的值都相同
public static int price; //用static修饰后 price变为斜体

1、类对象共享该内存信息
2、类加载时产生,直到类销毁的时候释放。生命周期长。
3、静态成员的访问方式,既可以通过对象名访问,也可以通过类名访问。
one.price (对象名访问) Cat.price(类名访问)
4、当static修饰方法时,该方法为静态方法,推荐采用类名调用,如Cat.eat();
5、有静态的属性和方法,静态方法中不能直接访问同一个类的非静态成员,只能直接调用同一个类中的静态成员。只能通过实例化后进行访问没有静态的类,没有静态的局部变量。

代码块{}

  • 普通代码块:在方法中的代码块叫做普通代码块。顺序执行,先出现,先执行。
  • 构造代码块:在类中的代码块叫构造代码块。创建对象时调用,优先与构造方法执行。
  • 静态代码块:构造代码块加上static关键字,就是静态代码块。类加载时调用,优先于构造代码块执行。 无论实例化多少个对象,只执行一次。

command+shift+f 行内容过长,换行快捷键。

三、Java封装综合案例

  • 在方法中通过对象作为参数,传递的是它的引用,可以通过引用获取该对象的所有信息。
  • 数组未实例化会造成空指针异常 java.lang.NullPointerException
package com.alan.model;

/**
 * 学生类
 * 
 * @author alan
 *
 */
public class Student {

    // 成员属性:学号、姓名、性别、年龄、专业对象
    private String studentNo;
    private String studentName;
    private String studentSex;
    private int studentAge;
    private Subject studentSubject;

    // 无参构造
    public Student() {

    }

    // 带参构造
    public Student(String studentNo, String studentName, String studentSex, int studentAge,Subject studentSubject) {

        this.setStudentNo(studentNo);
        this.setStudentName(studentName);
        this.setStudentSex(studentSex);
        this.setStudentAge(studentAge);
        this.setStudentSubject(studentSubject);
    }

    /**
     * 获取专业对象,如果没有实例化,先实例化后再返回
     * @return 专业对象
     */
    public Subject getStudentSubject() {
        if(this.studentSubject == null)
            this.studentSubject = new Subject(); //无参构造的重要性就提现出来了
        return studentSubject;
    }

    public void setStudentSubject(Subject studentSubject) {
        
        this.studentSubject = studentSubject;
    }

    public String getStudentNo() {
        return studentNo;
    }

    public void setStudentNo(String studentNo) {
        this.studentNo = studentNo;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public String getStudentSex() {
        return studentSex;
    }

    public void setStudentSex(String studentSex) {
        this.studentSex = studentSex;
    }

    public int getStudentAge() {
        return studentAge;
    }

    /**
     * 给年龄赋值。限定大于10,小于50,否则赋值为18
     * 
     * @param studentAge 传入的年龄
     */
    public void setStudentAge(int studentAge) {
        if (studentAge < 10 || studentAge > 50)
            this.setStudentAge(18);
        else
            this.studentAge = studentAge;
    }

    /**
     * 学生自我介绍的方法
     * 
     * @return 自我介绍信息,包括姓名、学号、性别、年龄
     *
     */
    public String introduction() {

        String str = "学生信息如下:\n姓名:" + this.getStudentName() + "\n学号:" + this.getStudentNo() + "\n性别:"
                + this.getStudentSex() + "\n年龄:" + this.getStudentAge()+ "\n所报专业名称:" + this.getStudentSubject().getSubjectName() + "\n学制年限:"
                        + this.getStudentSubject().getSubjectLife();
        return str;

    }

    /**
     * 学生自我介绍的方法
     * 
     * @param subjectName 所学专业名称
     * @param subjectLife 学制年限
     * @return 自我介绍信息,包括姓名、学号、性别、年龄、所学专业名称、学制年限
     */

    public String introduction(String subjectName, int subjectLife) {
        String str = "学生信息如下:\n姓名:" + this.getStudentName() + "\n学号:" + this.getStudentNo() + "\n性别:"
                + this.getStudentSex() + "\n年龄:" + this.getStudentAge() + "\n所报专业名称:" + subjectName + "\n学制年限:"
                + subjectLife;
        return str;
    }
    
    /**
     * 学生自我介绍的方法
     * @param sub1 传入学科对象
     * @return 自我介绍信息,包括姓名、学号、性别、年龄、所学专业名称、学制年限
     */
    public String introduction(Subject sub1) {

        String str = "学生信息如下:\n姓名:" + this.getStudentName() + "\n学号:" + this.getStudentNo() + "\n性别:"
                + this.getStudentSex() + "\n年龄:" + this.getStudentAge() + "\n所报专业名称:" + sub1.getSubjectName()
                + "\n学制年限:"+sub1.getSubjectLife();
        return str;

    }
}

学科类

package com.alan.model;

public class Subject {

    // 成员属性:学科名称、学科编号、学制年限、选课学生数组、报名选修的学生个数
    private String subjectName;
    private String subjectNo;
    private int subjectLife;
    private Student[] myStudents;
    private int studentNum;
    

    // 无参构造方法,定义一下,防止出现意外的错误。
    public Subject() {

    }

    // 带参构造方法 对学科名称、学科编号、学制年限赋值
    public Subject(String subjectName, String subjectNo, int subjectLife) {

        this.setSubjectName(subjectName); // 尽量采用此种赋值方式,而不用this.subjectName=subjectName
        this.setSubjectNo(subjectNo); // 因为set方法中有时候会包含一些逻辑校验
        this.setSubjectLife(subjectLife);
    }
    
    // 带参构造方法 对全部属性赋值
    public Subject(String subjectName, String subjectNo, int subjectLife,Student[] myStudent) {

        this.setSubjectName(subjectName); // 尽量采用此种赋值方式,而不用this.subjectName=subjectName
        this.setSubjectNo(subjectNo); // 因为set方法中有时候会包含一些逻辑校验
        this.setSubjectLife(subjectLife);
        this.setMyStudents(myStudent);
    }

    /**
     * 获取选修专业学生信息,如果保存学生信息的数组没有被初始化,则初始化长度为200
     * @return 保存学生信息的数组
     */
    public Student[] getMyStudents() {
        if(myStudents == null)
            myStudents = new Student[200];
        return myStudents;
    }

    public void setMyStudents(Student[] myStudents) {
        this.myStudents = myStudents;
    }

    public String getSubjectName() {
        return subjectName;
    }

    public void setSubjectName(String subjectName) {
        this.subjectName = subjectName;
    }

    public String getSubjectNo() {
        return subjectNo;
    }

    public void setSubjectNo(String subjectNo) {
        this.subjectNo = subjectNo;
    }

    public int getSubjectLife() {
        return subjectLife;
    }

    // 设置学制年限,必须大于0
    public void setSubjectLife(int subjectLife) {
        if (subjectLife <= 0)
            return;
        this.subjectLife = subjectLife;
    }
    public int getStudentNum() {
        return studentNum;
    }

    public void setStudentNum(int studentNum) {
        this.studentNum = studentNum;
    }

    /**
     * 专业介绍的方法
     * @return 专业介绍的相关信息 专业名称、专业编号、学制年限
     */
    public String info() {
        String str = "专业信息如下: \n" + "专业名称:" + this.getSubjectName() + "\n专业编号:" + this.getSubjectNo() + "\n学制年限:"
                + this.getSubjectLife();
        return str; 
    }
    
    public void addStudent(Student stu) {
        
        //1、将学生保存到数组中
        for(int i=0;i<this.getMyStudents().length;i++) {
            
            if(this.getMyStudents()[i]==null) {
                this.getMyStudents()[i] = stu;
                //2、将学生的个数保存到studentNum中
                this.studentNum = i+1;
                return;
            }
        }
    }

}

测试

package com.alan.test;

import com.alan.model.Student;
import com.alan.model.Subject;

public class NewTest {

    public static void main(String[] args) {

        
        Subject sub1 = new Subject("计算机科学与应用","J0001",4);
        System.out.println(sub1.info());
        System.out.println("=======================");
        Student stu1 = new Student("S01","张三","男",58,sub1);
        System.out.println(stu1.introduction());
        System.out.println("=======================");
        Student stu2 = new Student("S02","李四","男",19,sub1);
        System.out.println(stu2.introduction("计算机科学与技术", 4));
        System.out.println("=======================");
        Student stu3 = new Student("S03","王五","女",17,sub1);
        System.out.println(stu3.introduction(sub1));
        
        System.out.println("=======================");
        sub1.addStudent(stu1);
        sub1.addStudent(stu2);
        sub1.addStudent(stu3);
        
        System.out.println("学生的总数为:"+sub1.getStudentNum());
    }

}

四、Java继承

  • 子类继承父类可以直接获取父类的非私有成员(包括属性和方法)
    command+shift+o 快速导入包
  • 父类不能访问子类的特有成员(包括属性和方法)

方法重写

1、子类重写父类的方法
2、方法名相同、参数列表相同(参数顺序、个数、类型),方法返回值相同
3、方法的访问修饰符是允许有变化的,但是访问范围要大于等于父类的访问范围)
4、与方法参数名无关(string name)可以换成(string month)


访问修饰符

  • private 修饰的成员(属性和方法)只能在本类中访问
  • public 修饰的成员(属性和方法)访问范围最大,可以在本类、子类、跨包中访问。
  • protected 修饰的成员(属性和方法) 可以在本类,同包子类,同包非子类,跨包子类使用。跨包非子类中不允许
  • 默认 修饰的成员(属性和方法) 可以在本类,同包子类,同包非子类,不允许在跨包子类/非子类访问


    image.png

super关键字

  • 父类对象的引用,当子类中重写父类方法,需要调用父类的原有方法,需要加上super关键字。
  • 子类构造默认调用父类的无参构造,可以通过super关键字调用父类允许被访问的其他构造方法。必须放在第一行

继承的初始化顺序

  • 首先加载父类的静态成员,父类的静态代码块

  • 接着加载子类的静态成员,子类的静态代码块

  • 父类的成员属性赋值

  • 父类的构造代码块

  • 父类的构造函数

  • 子类的构造代码块

  • 子类的构造函数


    image.png
  • this 与 super 分别指定当前类和父类 不能在静态方法中使用


    image.png

Object类

  • Object类是所有类的父类
    Object中的 equals 相当于== 比较两个字符串的引用是否相同
    String中的 equals 被重写 比较两个字符串的值是否相等

  • tostring也是重写率非常高的一个方法

      /*tostring测试
       * 1、输出对象名时,默认会调用toString方法
       * 2、输出对象为:类型信息+@+地址信息 如:com.alan.animal.Animal@7b1d7fff
       * */
    

final关键字

  • final修饰class表示该类没有子类,不允许被继承。
  • String类 System类都是final修饰的
  • final 修饰方法,该方法不允许被重写,但是可以正常被子类继承使用
  • final 修饰方法内局部变量,该局部变量不允许被再次修改。
  • final 修饰类成员属性,没有赋值的话,只能在构造函数或者构造代码块中进行赋值
  • final修饰引用类型的变量,初始化后不能再指向另一个对象,但对象的内容可以改变。

注释简介

快捷键 option+/
@Override 给编译器看的,编译之后注解就没有用了。

五、Java设计模式

image.png

单例模式

  • 目的:使类的一个对象成为该类系统的唯一的实例。

  • 定义:一个类有且仅有一个实例,并且自行实例化向整个系统提供


    image.png
  • 饿汉式代码实现
    线程安全的

package com.alan.singleton;

//饿汉式:创建对象实例的时候直接初始化
public class SingletonOne {

    //1、创建类中的私有构造
    private SingletonOne() {
        
    }
    
    //2、创建该类型的私有静态实例
    private static SingletonOne instance = new SingletonOne();
    
    
    //3、创建公有静态方法返回静态实例对象
    public static SingletonOne getInstance() {
        return instance;
    }
    
    
}

测试


import com.alan.singleton.SingletonOne;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        //  SingletonOne one = new SingletonOne();  构造方法已经私有化,这种方式不允许
        
        SingletonOne one = SingletonOne.getInstance();
        SingletonOne two = SingletonOne.getInstance();

        System.out.println(one);
        System.out.println(two);  //所有的引用都会指向同一个对象

        
    }

}

  • 懒汉式代码实现
    线程不安全的
    通过1、同步锁 2、双重校验锁 3、静态内部类 4、枚举 解决线程不安全问题。
package com.alan.singleton;

// 懒汉式单例模式
public class SingletonTwo {

    // 1、创建私有构造方法
    private SingletonTwo() {
        
    }
    
    // 2、创建私有静态实例,静态的实例被共享,一定需要此修饰符
    private static SingletonTwo instance = null;
    
    // 3、创建静态公有方法返回静态实例对象
    public static SingletonTwo getInstance() {
        if(instance == null)
            instance = new SingletonTwo();
        return  instance;
    }
}
image.png

六、多态

封装和继承都是为多态准备的,是最核心也是最重要的概念。
多态的必要条件:
1、继承
2、重写
3、父类引用指向子类对象

向上转型

package com.alan.test;

import com.alan.animal.Animal;
import com.alan.animal.Cat;
import com.alan.animal.Dog;

public class Test {

    public static void main(String[] args) {
        
        Animal one = new Animal();
        /* 向上转型、隐式转型、自动转型
        父类引用指向子类的对象,可以调用子类重写父类的方法,以及父类派生的方法,无法调用子类独有方法
        小类转型为大类
        */
        Animal two = new Cat();
        Animal three = new Dog();
        one.eat();
        two.eat();
        three.eat();
    }
}

向下转型

package com.alan.test;

import com.alan.animal.Animal;
import com.alan.animal.Cat;
import com.alan.animal.Dog;

public class Test {

    public static void main(String[] args) {
        
        Animal one = new Animal();
        /* 向上转型、隐式转型、自动转型
        父类引用指向子类的对象,可以调用子类重写父类的方法,以及父类派生的方法,无法调用子类独有方法
        小类转型为大类
        */
        Animal two = new Cat();
        Animal three = new Dog();
        
        one.eat();
        two.eat();
        three.eat();
        System.out.println("============================");
        
        /*向下转型、强制类型转换
         * 子类引用指向父类对象、此处必须进行强转,可以调用子类特有的方法
         * 必须满足转换条件才能转换
         * */
        Cat temp = (Cat)two;
        temp.eat();
        temp.run();
        
    }

}

抽象类

  • 抽象类不允许实例化,可以通过向上转型,指向子类实例


    image.png

抽象方法

不允许包含方法体;子类中需要重写父类的抽象方法。否则,子类也要设置为抽象类。

  • 包含抽象方法的类一定是抽象类。
  • 抽象类可以没有抽象方法。

接口

package com.alan.tel;
/**
 * 具有上网功能的接口
 * @author alan
 *
 */

//接口可以设置的访问修饰符:public 默认

public interface INet {
    //接口中抽象方法可以不写abstract关键字,访问修饰符默认为public
    public void network();
    
    //default:默认方法 可以带方法体  jdk1.8之后新增的方法
    //可以在实现类中重写,并可以通过接口的引用调用
    default public void connection() {
        System.out.println("我是接口中的默认方法");
    }
    
    //static:静态方法 可以带方法体  jdk1.8之后新增的方法
    //不可以在实现类中重写,可以通过接口调用
    static void stop() {
        System.out.println("我是接口中的静态方法");
    }
    
    //接口中可以包含常量,默认会自动加上public final static
    
    int TEMP =20;
}

  • 一个类可以实现多个接口
  • 继承的父类和实现的接口中有同名方法,默认是实现父类中的同名方法。
  • 继承的父类的属性和接口中的常量同名,编译器无法分辨,会报错。

接口也可以实现继承关系,并且可以继承多个父接口

内部类

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。
与之对应,包含内部类的类叫外部类。
分为:1、成员内部类 2、静态内部类 3、方法内部类 4、匿名内部类

  • 成员内部类
package com.alan.people;


//外部类
public class Person {
    
    int age;
    
    public Heart getHeart() {
        
        return new Heart();
    }
    
    //成员内部类
    /*
     * 1、内部类在外部使用时,无法直接实例化,需要借由外部类信息才能完成实例化
     * 2、内部类的访问修饰符,可以任意,但是访问范围会受到影响
     * 3、内部类可以直接访问外部类的成员;如果出现同名属性,优先访问内部类中的定义
     * 4、可以使用外部类.this.成员方式,访问外部类中的同名信息
     * 5、外部类访问内部类信息,需要通过内部类实例,无法直接访问。
     * 6、内部类编译后.class文件命名:外部类$内部类.class
     * */
    class Heart{
        
        public String beat() {
            return "心脏在跳动";
        }
    }

}
package com.alan.people;

public class PersonTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        Person lili = new Person();
        
        //获取内部类对象实例,方式1:new 外部类. new 内部类
        Person.Heart myheart = new Person().new Heart();
        System.out.println(myheart.beat());

        //获取内部类对象实例,方式2:外部类对象.new 内部类
        myheart = lili.new  Heart();
        System.out.println(myheart.beat());

        //获取内部类对象实例,方式3:外部类调用方法返回内部类
        myheart = lili.getHeart();
        System.out.println(myheart.beat());

    }

}
  • 静态内部类
    有static修饰,静态内部类对象可以不依赖于外部对象,直接创建。
  • 方法内部类


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

推荐阅读更多精彩内容

  • java继承 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。 继承就是子类继...
    863cda997e42阅读 685评论 0 1
  • 一位阿爷醉醺醺步履蹒跚落座上半梦半醒唱粤曲扰了晨光与人群 一位阿婆少女心头扎双辫草莓夹黑点白衫绿长裙话了往日话醉事...
    远方的小溪阅读 201评论 2 4
  • 李萌萌同学在“六一”儿童节联欢会上,看到一名同学葫芦丝吹的真好听,一曲《月光下的凤尾竹》声音优美委婉悠扬,那种飘逸...
    LH来慧阅读 314评论 0 6