Java学习之面向对象与类之概述(匿名对象、封装、构造函数、this、静态等)

一、概述

1、面向对象的概述:

       java是一种面向对象的编程语言,也就是说对象是这种语言的基础,没有对象了,就没有了java。任何功能都是通过对象来实现的,就是将功能封装进对象,让对象去调用这些功能。这种思想是将数据作为第一位,而方法(功能或者说是算法)作为其次。我个人认为,这是对数据的一种优化,安全性更高,操作起数据来一更方便。
      那么将这种思想提升到一种境界就是:万物皆对象。

1、对面向对象的理解:
1)面向对象是相对面向过程而言的,且基于面向过程的。
2)面向对象是一种思想。
3)面向对象将功能封装进对象中,强调了具备功能的对象,主体是对象,将过程简化
4)在实际开发中,以对象为核心,先明确好对象,在实现具体功能,或者可是使用已有的对象。
5)面向对象的三个特征:封装性,继承性,多态性。

2、举例说明:
人是一个对象,人有吃饭,睡觉以及学习等等的行为(可称为功能),那么就是将吃饭、睡觉以及学习等功能封装进人这个的事物中,让人去执行这些功能,是人在调用这些方法,从而简化了过程。

二、类与对象

1、类与对象概述

1、类(class):可以理解为是构造对象的一个蓝图或者模板,是抽象的概念;反过来说,对象是以类为模型创造的具体实例,是对类的一种具体化、形象化。
类:对生活中事物的描述
对象:对类的具体实现,是实实在在存在的实体。

2、例如:汽车的设计
类:指的是汽车的设计图纸
对象:指实际生产出来的汽车。

示例:

/** 
需求|:定义一个汽车类,要求设计出汽车的型号(即名字),颜色,轮胎个数,行驶速度,并且让汽车行驶起来(即打印出每个汽车的颜色、轮胎数、速度) 
         并比较两辆汽车之间那个性能更好|:即速度快慢 
思路|: 
    1创建一个构造函数,即一个汽车类,对其的颜色,轮胎数。行书速度,速度,以及其方法,即行驶等进行初始化 
    2在main方法中创建一个汽车对象,并实现其功能 
    3构造一个方法,比较两辆车之间的速度大小 
*/class Car   
{  
    String name;  
    String color;  
    int nums;  
    double speed;  
    Car(String name,String color,int nums,double speed)  
    {  
        this.name = name;  
        this.color = color;  
        nums = 4;  
        this.speed = speed;  
        System.out.println(name + "是一辆" + color + ",轮胎数是:" + nums + ",可以行驶的速度是:" + speed);  
    }  
      
    public void compare(Car c)  
    {  
        if(this.speed > c.speed)  
        {  
            System.out.println(this.name + "行驶得更快。");  
            return;  
        }  
        System.out.println(c.name + "行驶得更快。");  
        return;  
    }  
}  
  
class CarDemo  
{  
    public static void main(String[] args)   
    {  
        Car a = new Car("奔驰","黑色的",4,500);  
        Car b = new Car("宝马","蓝色的",4,600);  
        a.compare(b);  
    }  
}

2、成员变量与局部变量:

在类中的不同位置定义变量,作用范围是不同的,下面简单区分一下,两种变量的不同:

1、作用范围:
a.成员变量:作用于整个类中
b.局部变量:作用于函数中,或者作用于语句块中。

2、在内存中的位置:
a.成员变量:在堆内存中,因为对象的存在才在内存中存在。
b.局部变量:在栈内存中,随着函数的结束而消亡

3、初始化方式:
a.成员变量:随着类的初始化而初始化,在堆内存中被加载,有默认值,可直接参与运算
b.局部变量:随着方法的加载而加载进栈内存中,无初始化值,必须被初始化才能参与运算

上面汽车的例子中,a、b和c是局部变量,定义在了方法中,存在于栈内存中;而name、color、nums和speed都是成员变量,存在于堆内存中,随着类的加载而加载。

3、匿名对象

1、简述:所谓匿名对象,就是创建的对象没有名字,直接使用。

2、使用方式:
1)使用方式一:当对对象的方法只调用一次时,可以使用匿名对象来完成,这样写比较简化。
      如果对一个对象进行多个成员调用,必须给这个对象起个名字
2)使用方式二:可以讲匿名对象作为实际参数进行传递,从而可以不用在main方法中创建一个变量,提高了编程效率,减少了代码书写。

      但是这个对象实体在方法结束后,垃圾回收机制会将其作为垃圾回收。而非匿名对象则不同,当不使用了,会在某一时刻被回收,或是随着主函数的结束而被回收。

二、封装

1、概述

1、定义:封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

2、好处:
a.将变化隔离
b.便于使用
c.提高重用性
d.提高安全性

3、原则:
a.将不需要对外提供的内容隐藏起来
b.把属性都隐藏,提供公共方法对其访问

4、说明:
a.私有仅仅是封装的一种表现形式,如包也是一种封装形式
b.之所以对外提供访问方式,就是因为可以在访问方式中加入逻辑判断等语句,对访问的数据进行操作,提高了代码的健壮性。

2、private 关键字

1、private是一个权限修饰符
2、用于修饰成员(成员变量和成员函数)
3、被私有化的成员只在本类中有效。
4、常用之一:将成员变量私有化,对外提供对应的set和get 方法对其进行访问,提高了对数据访问的安全性。
5、当把类中的所有构造函数私有化后,代表着该类是不能创建对象的,因为对象不能进行初始化操作的。

示例:

/**需求:定义一个private变量,并定义两个方法,一个返回其值,另一个提供新值位于60-100之间的数给变量 
思路:定义一个类,其属性包括一个变量,以及包括两个方法 
      一个方法返回变量的值,另一个方法提供60-100之间的值给变量 
 */  
  
class Virus  
{  
    private int newSeconds = 0;  
    public int getSeconds()  
    {  
        return newSeconds;  
    }  
  
    public void setSeconds(int x)  
    {  
        if(x>60 || x<100)  
        {  
            newSeconds = x;  
        }  
    }  
}  
  
class VirusText  
{  
    public static void main(String [] args)  
    {  
        Virus a = new Virus();  
        a.setSeconds(78);  
        System.out.println(a.getSeconds());  
    }  
}

3、成员访问权限比较

权限大小

成员修饰符 public protected default(默认) private
同一个类中 OK OK OK OK
同一个包中 OK OK OK NO
子类访问 OK OK NO NO
不同包中 OK NO NO NO

4、public类与源文件名

一个编译单元(个人理解为执行main函数所调用到的所有文件)中只能有一个public类,且这个类的文件名必须要和其类名相同,包括大小写也必须一样。

原因:
1、一个编译单元只能有一个public类的原因:
第一、public的意思是所有类都能访问,包括包以外的类。public是作为这个编译单元的公开接口存在的。
第二、java程序的入口是main方法,所以被定为public的这个类一定是main方法的类,且这个类的名称要和文件名一直,因为虚拟机是要开始找main方法这个入口的。
第三、你可以根据需要,添加任意辅助功能的public权限的类,但是如果这个编译单元(注意是编译单元)里面有两个或以上public类的话,那么编译器就会报错。

建议:
第一、不要在一个源文件中写多个类。在标准的java代码编写时,无论代码量是多少,最好一个源文件只有一个类或接口(即使是接口也要如此),因为java是面向对象的语言,每个类都是抽象的结果,所以每个类要单独写在一个源文件里。
第二、只要要有一个是public类,虽然可以在编译单元中没有public类,即没有公开的接口,可在同一个包中访问,但是这样就将这个包都封闭了,是没意义的。如果没public,就可以随意给文件起名,可以不和类名相同。

2、被public修饰的类与文件名必须同名的原因:
第一、java是被编译执行的,它在运行时并不是将你写的所有类都先加载一遍的,而是当遇到import或使用到了其他类的时候,才会去在文件目录中找相应的class文件的。
第二、对于一个public类。上面也说了,是可以被项目中的任何一个类引用的,只需通过import导入即可。既然是作为虚拟机入口的main函数要用public修饰而成为一个公共接口,那么将类名和文件名一一对应就可以方便虚拟机在相应的路径(包名)中找到相关的信息;但是你如果不这么做,虚拟机很难去找,开销也会跟着增大的。

简单总结:
public作为一个公共接口(此接口非interface这个接口),修饰作为虚拟机入口的main函数,就是为了方便虚拟机找到相应的类,从而节省开销。

三、对象与函数

1、main函数:

我们刚开始接触java的时候就是用到了main函数,那么主函数是什么呢?在此分别对主函数的各个关键字及修饰符进行简单说明:

public static void main(String [] args){....}

1、主函数:是一个特殊的函数,作为程序的入口,可以被JVM识别并调用,它的格式是固定的。

2、主函数的定义:
1)public:代表着该函数的访问权限是最大的。
2)static :代表着主函数随着类的加载就已经存在了,一边执行函数中的代码。
3)void :主函数没有具体的返回值,只是作为执行程序的入口。
4)main :不是关键字,和其他的函数名类似,只不过别定义为一个特殊的单词,可以被JVM识别。
5)(String [] args)):函数的参数,参数类型是一个String类数组,元素为字符串。字符串类类型是数组,args是一个变量名,是约定俗成的,早期被写成arguments;如果改写成其他名称也是可以的。

3、注意:
可以重载主函数,但是虚拟机只识别固定格式的主函数,即public static void main(String [] args){....}

2、构造函数

先看一个简单的小程序

//创建一个简单的雇员类  
public class Employee   
{  
    //构造Employee函数  
    public Employee(String name,int age,double salary)  
    {  
        //将变量定义为private  
        private this.name = name;  
        private this.age = age;  
        private this.salary = salary;  
    }  
      
    {  
        System.out.println("我来工作了");  
    }  
  
    //访问器方法,获取name  
    public String getName()  
    {  
        return name;  
    }  
    //获取age  
    public int getAge()  
    {  
        //限制age的值  
        if (age<18)  
        {  
            System.out.println("不好意思啦,我们不接收未成年人!嘿嘿");  
            return;  
        }  
        return age;  
    }  
    //获取salary  
    public double getSalary()  
    {  
        return salary;  
    }  
    //修改雇员工资:涨byPercent个百分点的工资  
    public void setSalary(double salary,double byPercent)  
    {  
        salary + = salary*byPercent/100;  
    }  
} 

其中的public Employee(String name,int age,double salary)就是对这个类Employee的构造函数

1、特点:
a.函数名与类名相同
b.不用定义返回类型,括号中的参数可以没有,也可以有多个。
c.不可以写return语句
d.构造函数总是伴随着new操作一起被调用。
e.细节:当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数,即:类名(){}。但当类中自定义了构造函数后,默认的构造函数就不存在了。也就是说,每一个类中一定含有一个构造函数。

2、作用:给对象进行初始化

3、注意:
a.默认构造函数的特点
b.多个构造函数时以重载形式存在的。

3、构造函数与一般函数的区别:运行上不同
构造函数时在对象一建立就运行,是给对象初始化的。且一个对象建立后,构造函数只运行一次。
一般函数时对象调用才执行,是给对象添加对象具备的功能的。一般函数可以被该对象多次调用。
注:
一般函数是不能调用构造函数的,因为一般函数中不能定义this,而构造函数中可能存在this。

4、何时定义构造函数:
当分析事物时,该事物存在具备一些特性或行为,那么将这些内容定义在构造函数中。也就是说,一类事物一出现就应该存在的特性,这就需要构造函数对其进行初始化。

5、构造代码块:
如上面的小程序,其中打印的“我来工作了”这个语句块就是构造代码块。它和构造函数作用类似,只不过仅用一对花括号括起来即可。
1)作用:给对象进行初始化,对象一建立就运行,且优于构造函数执行,即在构造函数前加载。
2)与构造函数区别:
构造代码块是给所有对象进行统一初始化,是所有对象的共性初始化方式内容。如任何孩子出生都要哭几声。

构造函数是给对应的对象初始化,不同的对象有各自的特性,需要选择不同的构造函数初始化。

<<<<<------------------------------------------------------------------------------------------------------------------->>>>>
补充:
this关键字:
1、this:表面上,是用于区分局部变量和成员变量同名的情况。即this代表着当前对象的引用。

2、this的用法:
a.用于区分同名变量的情况。当局部已经定义了变量,当需要找成员中的变量,且变量名相同时,为了区分局部变量和成员变量的相同变量名,可以使用this加以区分。
b.用于构造函数间的调用。

3、特点:
1)this代表了本类的对象,即代表了它所在函数所属对象的引用,也就是说,哪个对象调用这个函数,this就代表哪个对象。
2)一般情况下,this都是被省略的,需要使用的时候才需加上。

如上面构造函数中的this的使用。

4、this应用:
当定义类中的功能时,该函数内部要用到调用该函数的对象时,这时用this来表示调用这个函数的对象。
只要本类功能内部使用了本类对象,都用this表示。

5、在构造函数中的应用:
this语句:用于构造函数之间的互相引用。且只能放在构造函数的第一行,否则编译失败。
原因:初始化的动作要先执行,因为自身的特性要先具备;如果初始化中还有初始化,要限制性更细节的操作,然后再执行自己所需求的初始化。

注意:
不允许两个构造函数间相互调用this语句,否则会出现死循环。
一般函数中不能定义this语句。

<<<<<------------------------------------------------------------------------------------------------------------------->>>>>

3、static之静态函数

我们在学习java的最初就接触到了static这个修饰main方法的修饰符,那么static在java中有什么特点和作用呢?下面是对static的总结的几点:

一)总体来说static有这么几个特点:

1、随着类的加载而加载,在类中生命周期最长

2、优先于对象而存在

3、可以被所有对象共享

4、可以直接被类名调用

二)static的用法:
1、修饰成员:包括成员变量和成员方法
当成员被static修饰后,就多了一种调用方式,即可以被对象和类名调用

需要注意的一点:static绝对不能修饰局部变量。为什么呢?

局部变量的作用域就是它所在的方法或代码块中,而static的变量刚是定义在类中方法体外,是作为整个类共同使用的,它从类加载开始就存在,而局部变量在它所在的方法或代码块结束后就要被回收的。所以是不能修饰局部变量的

1)静态常量:
例如:在Math类中定义了一个静态常量PI

public class Math    
{    
    ...    
    public static final double PI = 3.14159265358979323846;//final将PI设置为不可再定义的常量  
    ...    
}

如果省略了static,PI就变成了一个实例常量,那么,每一个Math对象就都有自己的一个PI拷贝了,这样的话,对内存也是一种占用。
2)静态变量
如果将变量定义为static,那么每个类中只有这样一个变量。例如:

class Student  
{  
    private int id;  
    private static int nextId = 1;  
    //获取id的访问器  
    public int getId()  
    {  
        return id;  
    }  
    public void setId()  
    {  
        id = nextId;  
        nextId++;  
    }  
}

每个学生都有自己的一个id号,但这个Student的所有对象都共享一个nextId,即使不存在对象,也仍存在nextId,因为它是属于类的,而不属于任何独立的对象,所以它是随着类的加载而加载的,随着类的消亡而消亡的。

3)静态方法:
静态方法是一种不向对象进行操作的方法。当方法被static修饰的时候,此方法是用类名.方法名的方式使用的,当然也可以用对象名.方法名,但是这样就会产生误解,会让别人以为这个方法是非静态的,这样就有些不合理了。但是静态方法有一点需要注意的是:静态方法只能访问静态成员,因此静态方法也就不能定义this和super等关键字了。

那么在什么时候用到静态方法呢?
第一、当一个方法不需要访问对象是,其中所需的参数都是通过显示参数提供的。比如说Math.sqrt(double n)
第二、一个方法只需要访问累的静态变量时,如Person.getCountry();

private static String country = "CN";//因为国家是共有的,共享  
public static void getCountry()  
{  
    return country;  
}

3、静态的应用:
当每个应用程序都有共同之处,可将其封装,提高其复用性。
需要注意的是:
a.对象时用于封装数据的;
b.对数据的操作方法,若没用到方法中特有的数据,则无需创建对象而占用多余的内存。

4、静态代码块
特点:a.随着类的加载而执行,且优先于主函数;b.只执行一次,类再创建对象,则不再执行,已经存在于内存中。
格式:

static  
   {语句}

5、静态是用注意事项:
1)静态方法只能访问静态成员,非静态方法既能访问静态也可以访问非静态
2)静态方法中不可定义this,super等关键字,因为静态优先于对象存在,所以静态方法中不可以出现this
3)主函数是静态的。

6、静态有利有弊:
好处:对对象的共享数据惊醒单独空间的存储,节省空进。没必要每个对象中都要存储一份,可以直接被类名调用
弊端:生命周期过长。访问出现局限性,因为静态只能访问静态。

举例:

class Student  
{  
    private static String country = "CN";//因为国家是共有的,共享  
    private int id;  
    private static int nextId = 1;  
    //静态代码块  
    static  
    {  
        System.out.println("Hello");  
    }  
    public static String getCountry()  
    {  
        return country;  
    }  
    public int getId()  
    {  
        return id;  
    }  
    public void setId()  
    {  
        id = nextId;  
        nextId++;//前一个人获取id后,然后一个人获取下一个id时就加1  
    }  
}  
  
class StudentText  
{  
    public static void main(String [] args)  
    {  
        Student st1 = new Student();  
        st1.setId();  
        System.out.println("st1'country = " + Student.getCountry() + "; st1id = " + st1.getId());  
        Student st2 = new Student();  
        st2.setId();  
        System.out.println("st2'country = " + Student.getCountry() + "; st2id = " + st2.getId());  
    }  
}

运行结果如下:

Paste_Image.png

四、单例设计模式

在java中存在很多通用的设计模式,今天我简单总结一下单例设计模式:
解决问题:解决一个类在内存中只存在一个对象的问题(比如说一个软件中的配置文件)

1、如何保证对象的唯一性:

1、为避免建立过多的该类对象,应首先禁止其他应用程序创建该类对象。
2、为让其他应用程序访问到该对象,在本类中自定义一个对象,为避免直接访问该对象,要对其进行私有化。
3、提供访问方式,便于其他程序对自定义对象的访问,提供的访问方法是公有的。
对象保证是惟一的了,那么该如何具体实现呢?

2、使对象唯一性的步骤:

1、将构造函数私有化
2、在类中创建一个本类对象,并设置为私有的
3、提供一个公有的方法获取该对象,便于使用

3、单例设计模式的具体表现形式

具体代码如下:
1、饿汉式:先初始化对象,类一进内存就加载

//饿汉式  
class Single   
{  
    private Single(){}  
    private static Single s = new Single();  
    public static  Single getSingle()  
    {  
        return s;  
    }  
}  
  
class SingleText  
{  
    public static void main(String [] args)  
    {  
        Single s1 = Single.getSingle();  
        Single s2 = Single.getSingle();  
        if (s1==s2)  
            System.out.println(true);  
        else  
            System.out.println(false);        
    }  
}

2、懒汉式:类进内存,对象还没有存在,只有调用了getSingle方法时,才建立对象

//懒汉式  
class Single   
{  
    private Single(){}  
    private static Single s = null;  
    public static Single getSingle()  
    {  
        if (s==null)   
            s = new Single();  
        return s;  
    }  
}  
  
class SingleText  
{  
    public static void main(String [] args)  
    {  
        Single s1 = Single.getSingle();  
        Single s2 = Single.getSingle();  
        if (s1==s2)  
            System.out.println(true);  
        else  
            System.out.println(false);        
    }  
}

运行的结果是:true;这是因为s1和s2引用的是同一个对象,所以符合条件。

但是对于第二种懒汉式的单例设计模式,会出现一些小小的问题,当一个线程调用时,是没什么问题的,如果多个线程调用此种方式,那么就会出现问题。

class Single  
{  
    private static Single s = null;  
    private Single(){}  
    public static Single getInstance()  
    {  
        if (s == null)  
        {  
            synchronized(Single.class)  
            {  
                if (s == null)  
                    s = new Single();  
            }  
        }  
        return s;  
    }  
}

比如说,当A调用时,当读到if(s1==null) 时,可能就停在这了,然后cpu再调用B,B也读到if(s1==null)这停下了,cpu再切换到A,接着创建一个对象,A就执行完了;之后B也向下执行,又创建一个对象;此时,对象就不唯一了,就破坏了对象的唯一性的初衷。那么解决方案是这样的:
这利用了锁的机制。synchronized是java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。这涉及到了多线程的问题。在这个例子中,比如说,当A调用时,当读到第二个if(s1==null) 时,可能就停在这了,然后cpu再调用B,B读到第一个if(s1==null)这停下了,因为加上synchronized后,A进去就相当于将其他的调用锁在外面的语句上了,要先执行完A,那么A执行完后,就已经创建了一个对象;当B再读到第二个if(s1==null)的时候不符合就直接结束了。如果再有其他C或D等调用的时候,就直接不符合第一个(s1==null)的条件,所以直接返回s。在这里,我们再来看看关于懒汉式的多线程问题:

上面的懒汉式的写法,是效率比较高的,先看看下面一段代码,比较一下,就会清晰很多:

class Single  
{  
    private static Single s = null;  
    private Single(){}  
    public static synchronized Single getInstance()  
    {  
        if (s == null)  
            s = new Single();  
        return s;  
    }  
}

在这两种方式中,含有双重判断(称为第一种,无双重判断的为第二种)的效率更高,为什呢?虽然第一种和第二种都要先判断一下,但是对于第一种,第一个线程执行完后,s不为null了,那么后面只需要判断s是否为null即可,而对于第二种,要先判断锁,锁里没有线程,再进入,然后再判断一下s是否为null,这样一来,就要判断两次,所以,效率会更低。所以,对于双重判断,是可以提高效率的。

问题是解决了,但是相比之下,还是第一种饿汉式的单例设计模式更好一些,是一种建议使用的方式。

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

推荐阅读更多精彩内容