Java开发基础_03
admin
2024-01-21 17:33:43
0

五. 面向对象

面向过程 : 以函数为最小单位(方法),数据独立于函数之外,以过程步骤为主(怎么做)—执行者

面向对象 : 以类对象为最小单位,类包括数据+方法,是以对象为主(谁来做)—指挥者

1. 面向对象的基本特征

  • 封装 , 继承 , 多态

2. 类和对象

    • 类 : 是一类具有相同特性的事物的抽象描述,是一组相关属性和行为的集合,可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该事物
    • 属性 : 状态信息
    • 行为 : 该事物能做什么
    举例:小猫
    属性:名字,颜色,体重
    行为:走,跑,叫
    
  • 对象 :

    • 对象 : 是一类事物的具体的体现,对象是类的一个实例,必然具备该事物的属性和行为
    举例:小猫
    属性:tom,yellow,5KG
    行为:贴墙走,喵喵叫
    
  • 类与对象的关系

    • 类是对一类事物的描述,是抽象的
    • 对象是一类事物的实例,是具体的
    • 类是对象的模板,对象是类的实体
  • 创建类

    • 成员方法 : 对应事物的一些行为
    • 成员变量 : 对应事物的属性
  • 类的定义

    • public class 类名 {//成员变量 //成员方法}
    • 定义类 : 就是定义类的成员,包括成员变量和成员方法
    • 成员变量 : 和以前定义变量几乎是一样的,只不过位置发生了改变,在类中,在方法外
    • 成员方法 : 和以前写的main方法格式类似,只不过功能和形式更丰富,在类中,在方法外
    package com.kgc01;
    public class Demo01Person {//成员变量String name;        //姓名int age;            //年龄String gender;      //性别//成员方法public void walk(){System.out.println("走路");}public String display(){return "名字是:"+name+",年龄是:"+age+",性别是:"+gender;}  
    }
    
  • 对象的创建

    • new 类名() //匿名对象
    • 类名 对象名 = new 类名(); //把创建的对象保存下来
    • 对象是引用数据类型
    package com.kgc01;
    public class PersonTest {public static void main(String[] args) {//创建一个对象Demo01Person p1=new Demo01Person();p1.name="小红";p1.age=18;p1.gender="女";p1.walk();p1.display();System.out.println(p1.display());}
    }
    
    //在一个java文件里创建
    package com.kgc01;
    class Student{String name;public void study(){System.out.println("好好学习,天天向上");}
    }
    public class TestStudent {public static void main(String[] args) {Student s1 = new Student();s1.name="张三";System.out.println(s1.name);s1.study();}
    }
    

3. 成员变量

  • 成员变量

    • 分类

      • 实例变量 : 也叫对象属性,属于某个对象的,通过对象来使用
      • 类变量 : 属于整个类的,不是属于某个实例
    • 声明一个实例变量

      • [修饰符] class 类名 {
      • [修饰符] 数据类型 属性名; //属性有默认值;
      • [修饰符] 数据类型 属性名 = 值; //属性有初始值;
      • }
      • 属性的类型可以是任意类型,基本数据类型,引用数据类型(类,接口,数组)
    • 使用实例变量

      • 实例变量在本类中可以直接使用
      package com.kgc01;
      public class circle {
      double r;public double getArea(){return 3.14*r*r;}
      }
      
      • 实例变量在其他类中使用,需要通过对象名.实例变量的方式
      package com.kgc01;
      public class TestCircle {public static void main(String[] args) {circle c = new circle();c.r=5;System.out.println("面积是:"+c.getArea());}
      }
      

4. 实例变量

  • 实例变量的特点

    • 成员变量有默认值
    • 基本数据类型
      • 整数(byte , short , int , long) 0
        • 浮点数(float , double) 0.0
        • 字符(char) ‘\u0000’
        • 布尔(boolean) false
      • 引用数据类型(数组,类,接口,字符串) null
    • 实例变量的值,相对每个对象来说都是独立的
  • 实例变量的赋值

    • 在声明属性时,显式赋值,在创建每个对象后,这个属性的值就不是默认值了,就是这个初始值
    • 通过对象属性来赋值,
  • 实例变量和局部变量的区别

    • 在类中的位置不一样

      • 实例变量 : 在类中方法外
      • 局部变量 : 在方法中或者方法声明上(形式参数)
    • 作用范围不一样

      • 实例变量 : 在类中直接使用,其它类中可以通过"对象名.实例变量来使用
      • 局部变量 : 当前方法的作用域
    • 初始化的值不同

      • 实例变量有默认值
      • 局部变量没有默认值,必须先定义赋值再使用
    • 在内存中的位置不同

      • 实例变量 : 堆内存
      • 局部变量 : 栈内存
    • 生命周期不同

      • 实例变量 : 随着对象的创建或类的加载而存在,随着对象的消失而消失
        • 就是说没有创建对象,就不会在堆内存中分配空间,创建一个就会分配一个
      • 局部变量 : 随着方法的调用而存在,随着方法的调用完而消失
        • 就是说,方法没有被调用时,该局部变量不会再栈内存中分配空间,调用一次分配一次
      package com.kgc01;
      //需求: 声明员工类, 包含姓名 ,性别,薪资,三个实例变量,  并创建员工对象,打印员工信息
      class Staff{                            //声明员工类String name;                        //姓名String gender;                      //性别double price;                       //薪资
      }
      public class Demo03 {public static void main(String[] args) {Staff staff = new Staff();      //创建员工对象staff.name="张三";staff.gender="男";staff.price=10000;System.out.println("姓名:"+staff.name);System.out.println("性别:"+staff.gender);System.out.println("薪资:"+staff.price);} }
      

5. 成员方法

  • 成员方法

    • 方法也叫函数,是一个独立功能的定义,是一个类中最基本的功能单元,把一个功能封装成一个方法,可以实现代码的重用,减少代码量

    • 方法的使用原则

      • 必须先声明后使用
      • 不调用不执行,调用一次执行一次,方法压栈一次
    • 成员方法的分类

      • 实例方法 : 属于对象的方法,由对象来调用
      • 静态方法 : 也叫类方法,属于整个类的,不是属于某个实例,由类名来调用,后面有static
    • 语法格式

    修饰符 返回值类型 方法名([参数列表:参数类型1 参数名1,参数类型2 参数名2...]){方法体;- [return 返回值;]- }
  • 修饰符 : public 目前是固定的写法
  • 返回值类型 : 表示方法运行的结果的数据类型,方法执行后将结果返回给调用者
    • 基本数据类型
    • 引用数据类型
    • 无返回值类型 void
  • 方法名 : 见名知意小驼峰
  • 参数列表 : 方法中使用的数据类型,需要通过参数传递的形式将数据传递过来,可以是基本数据类型,也可以是引用数据类型,也可以没有参数什么都不写
  • 方法体 : 实现具体功能的代码
  • return : 结束方法,并将方法的结果返回回去
    • 如果返回值类型不是void,方法体中必须有return返回值,返回值的类型要与声明的返回值的类型一致
    • 如果返回值的类型时void,return后不用跟返回值,甚至可以不写return语句
    • return语句后,不写其他代码,否则会报错
  • 方法声明时,必须在类,方法外
  • 方法的调用
    • 单独调用
      • 对象名.方法名(参数);
    • 输出调用
      • System.out.println(对象名.方法名(参数));
    • 赋值调用
      • 数据类型 变量名 = 对象名.方法名(参数);
 package com.kgc02;//定义计算两个整数和的方法,返回值类型,计算的结果是int,参数,两个都是int类型public class Demo01Add {public static void main(String[] args) {Add a = new Add();int sum = a.getAdd(1,2);//第一种System.out.println("sum = "+sum);//第二种System.out.println(a.getAdd(2,3));}}//加法类class Add{//方法public int getAdd(int a,int b){return a+b;}}```- 形参 : 在定义方法时,方法名后面括号中的变量名称为形式参数(简称形参),即形参出现在方法定义中- 实参 : 调用者方法中调用另一个方法时,方法名后边括号中的参数称为实际参数(简称实参),即实参出现在调用者方法中- 总结 : 调用时,需要通过方法名来识别调用哪个方法- 调用时,需要传"实参",实参的个数,类型顺序,需要与形参列表一一对应,如果方法没有形参,就不需要也不能传实参- 调用时,如果方法有返回值,可以接受或处理返回值的结果,如果方法返回值的类型是void,不需要也不能接收和处理返回值结果```java
package com.kgc02;
//比较两个整数是否相等: 需要定义一个方法,两个参数, 有返回值
class Equals{public boolean getEqual(int a,int b){return a==b;}
}
public class Demo02Equal {public static void main(String[] args) {Equals equals = new Equals();System.out.println(equals.getEqual(1,1));}
}
  • 可变参数

    • 一个方法只能有一个可变参数
    • 可变参数必须是形参列表的最后一个
    package com.kgc02;public class Demo03 {public static void main(String[] args) {//实例化对象Sum s = new Sum();int array[] = {1,2,3,4,5,6,7,8};System.out.println(s.mySum(array));System.out.println(s.mySum2(array));}
    }
    class Sum{public int mySum(int[] a){int sum=0;for (int i=0;isum+=a[i];}return sum;}public int mySum2(int...arr){int sum=0;for (int i=0;isum+=arr[i];}return sum;}
    }
    
    //定义求1-n个整数中的最大值
    package com.kgc02;
    import java.util.Arrays;
    public class Demo04Max {public static void main(String[] args) {int[] arr = new int[]{3,4,56,67,81,34,70};Max max = new Max();System.out.println(max.myMax(arr));System.out.println(max.myMax(1,3,454567,768,4356,678,435,4563));}
    }
    class Max{public int myMax(int...a){Arrays.sort(a);return a[a.length-1];}
    }
    

6. 方法的重载

  • 在同一个类中,允许存在一个以上的同名方法,只要让他们的参数列表不同即可,与修饰符和返回值类型无关

  • 参数列表 : 数据类型个数不同,数据类型不同,数据类型顺序不同

  • 重载方法的调用 : JVM是通过方法的参数列表调用不同的方法

    //比较两个数据是否相等,分别为两个byte类型,两个short类型,两个long类型
    package com.kgc02;public class Demo05Equals {public static void main(String[] args) {MyEqual myEqual = new MyEqual();byte a1=10;byte a2=20;System.out.println(myEqual.equals(a1,a2));short b1=10;short b2=10;System.out.println(myEqual.equals(b1,b2));int c1=10;int c2=20;System.out.println(myEqual.equals(c1,c2));long d1=10;long d2=10;System.out.println(myEqual.equals(d1,d2));}
    }
    class MyEqual{public String equals(byte a,byte b){return a==b?"相等":"不相等";}public String equals(short a,short b){return a==b?"相等":"不相等";}public String equals(int a,int b){return a==b?"相等":"不相等";}public String equals(long a,long b){return a==b?"相等":"不相等";}
    }
    

7. 封装

  • 封装

    • 隐藏对象内部的复杂性,只对外公开简单的接口,便与外界访问,从而提高系统的可扩展性,可维护性,通俗的将就是把该隐藏的隐藏起来,该暴露的暴露出来,这就是封装的设计思想
  • 属性的封装

    • 将属性隐藏起来,若需要访问某个属性,我们只需要提供公共的方法对其访问
  • 属性封装的目的

    • 隐藏类的实现细节
    • 让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里面加入控制逻辑,限制对成员变量的不合理访问
    • 可以进行数据的检查,从而有利于保证对象信息的完整性
    • 便于修改,提高代码的可维护性
  • 实现步骤

    • 使用private 修饰成员变量
      • private 数据类型 变量名;
    • 对外提供 getXXX 方法 setXXX方法,可以访问成员变量
  • 权限修饰符

    修饰符在同一个类中在同一个包中子类中任何地方
    private可以不可以不可以不可以
    默认修饰符可以可以不可以不可以
    protected可以可以可以不可以
    public可以可以可以可以
    • 对于类成员 : 四种权限修饰符都可以使用
    • 对于外部的类 : 只能使用public和缺省两种
    package com.kgc01;
    //定义一个学生类Student,声明 姓名和成绩,实例变量,私有化,提供get/set方法,getinfo方法用于返回学生的对象信息
    public class Student {private String name;private int score;public void setName(String n){name=n;}public String getName(){return name;}//----------------------------------------------------------public void setScore(int s){score=s;}public int getScore() {return score;}//----------------------------------------------------------public String getInfo(){return "姓名:"+name+"\t"+"成绩:"+score;}
    }
    
    package com.kgc01;
    import java.util.Scanner;//定义一个测试类TestStudent,main中创建一个可以装3个学生的对象的数组,并且按照学生成绩排序,显示学生信息
    public class Test {public static void main(String[] args) {Scanner sc = new Scanner(System.in);//创建一个可以装3个学生的对象的数组Student[] s = new Student[3];//赋值s[0]=new Student();s[0].setName("张三");s[0].setScore(89);s[1]=new Student();s[1].setName("李四");s[1].setScore(98);s[2]=new Student();s[2].setName("王五");s[2].setScore(69);//先打印目前的顺序for (int i = 0; i < s.length; i++) {System.out.println(s[i].getInfo());}System.out.println("--------------------");//冒泡排序for (int i = 0; i < s.length; i++) {for (int j = 0; j < s.length-i-1; j++) {if (s[j].getScore()>s[j+1].getScore()){Student temp = s[j];s[j]=s[j+1];s[j+1]=temp;}}}for (int i = 0; i < s.length; i++) {System.out.println(s[i].getInfo());}}
    }
    

8. 构造器

  • 构造器

    • 又称为构造方法,因为跟方法长得很像,和方法还有区别
    • 作用
      • 要创建一个类的实例对象,必须调用一个对象的构造器,来完成类的实例初始化过程,实例初始化过程就是为实例变量赋初始值的过程
      • 无论是否自定义构造方法,所有的类都有一个无参构造方法,一旦自定义了构造方法,就不送
    • 格式
      • 修饰符 构造器名(){实例初始化代码}
      • 修饰符 构造器名(参数列表){实例初始化代码}
    public class Test01Student {private String name;private int age;//无参构造public Test01Student(){System.out.println("无参构造");}//有参构造public Test01Student(String n,int a){name=n;age=a;}
    
    • 注意事项 :
      • 构造器的名必须与他所在的类名相同
      • 他没有返回值,所有不需要返回值类型,甚至不需要void
      • 如果你不需要提供构造器,系统会给出无参构造器,并且该构造器的修饰符默认与类的修饰符相同
      • 如果你提供了构造器,系统将不再提供无参构造器,除非你自己定义
      • 构造器是可以重载的,即定义参数,也可以不定义参数
      • 构造器不能被 static final,…修饰
    练习:
    package com.kgc01;
    /*1. 声明一个员工类:1. 属性: 编号,姓名,薪资,性别, 要求属性私有化,提供get / set方法2. 提供无参构造和有参构造3. 提供 getInfo()
    2. 测试类中main中,分别用无参构造和有参构造 创建员工对象, 调用getInfo方法
    */
    public class Test02Emp {private int id;private String name;private double price;private String gender;//无参public Test02Emp(){}//有参public Test02Emp(int a,String b,double c,String d){id=a;name=b;price=c;gender=d;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getInfo(){return "编号:"+getId()+"\t"+"姓名:"+getName()+"\t"+"薪资:"+getPrice()+"\t"+"性别:"+getGender()+"\t";}
    }package com.kgc01;
    //2. 测试类中main中,分别用无参构造和有参构造 创建员工对象, 调用getInfo方法
    //    private int id;
    //    private String name;
    //    private double price;
    //    private String gender;
    public class Test02Demo {public static void main(String[] args) {Test02Emp emp = new Test02Emp();emp.setId(1);emp.setName("李四");emp.setPrice(2000);emp.setGender("女");System.out.println(emp.getInfo());Test02Emp emp1 = new Test02Emp(2,"张三",1000,"男");System.out.println(emp1.getInfo());}
    }
    
  • this

    • 我们发现setXXX方法中形参名和构造器形参名不符合见名知意的规定,如果非要修改成和成员变量名一致的,会赋值失败,只能使用this关键字来解决重名问题
    • this含义
      • this代表当前对象引用(地址值),即对象自己的引用
      • this可以用于构造器中,表示正在创建的那个实例对象,即正在new谁,this就代表谁
      • this可以用在实例方法中,表示该调用方法的对象,即谁在调用,this就代表谁
    • 格式
      • this.成员变量 或 this.成员方法
        public Test02Emp(int id, String name, double price, String gender) {this.id = id;this.name = name;this.price = price;this.gender = gender;}
    
  • java语言编写类的标准规范

    public class ClassName{
    //成员变量
    //构造方法//无参构造  必须有//有参构造  建议有
    //setXXX()
    //getXXX()
    //其他成员方法
    }
    

9. 包

    • 包的作用
      • 避免类的重名,有了包之后,类的全名就变为了 包.类名
      • 分类组织管理众多的类
        • 常用的类
          • java.lang 包中有 String , Math , Integer , System
          • java.util 实用工具类 集合,日期,数组相关,输入相关,随机相关
          • java.sql 数据库相关
          • java.awt 窗口相关
      • 控制某些类型或成员的可见范围
    • 使用其他包的类
      • 前提 : 被使用的类或成员的权限是大于缺省的
      • 使用类的全名称 java.util.Scanner import = new java.util.Scanner(System.in)
      • 使用import语句,代码可以使用简称

10. 继承

  • 继承的由来

    • 多个类中存在相同的属性和行为,将这些内容抽取到单独的一个类中,那么多个类中无需再定义这些属性和行为,只需要和抽取出来的类构造某种关系
    • 其中多个类可以成为子类,也叫派生类,多个类抽取出来的这个类称为父类,超类或基类
    • 继承描述的是事物之间的所属关系,这种关系是 is a 的关系,如:猫是动物,狗也是动物,父类就能更通用,子类更具体,我们通过继承,可以使多种事物之间形成一种关系体系
  • 继承 : 就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性,相同的行为

  • 好处 :

    • 提高代码的复用性
    • 提高代码的可扩展性
    • 类与类之间产生了关系,是学习多态的前提
  • 格式 :

    • 通过extends 关键字,可以声明一个子类继承另外一个父类
      • 修饰符 class 父类{}
      • 修饰符 class 子类 extends 父类
    package com.kgc02;
    /*
    定义动物类,作为父类*/
    public class Animal {//定义name属性public String name;//定义age属性public int age;//定义动物吃东西的方法public void eat(){System.out.println(age+"岁的"+name+"在吃东西--animal");}
    }
    -----------------------------------------------------------------------------package com.kgc02;
    //定义猫类,继承动物
    public class Cat extends Animal{//定义一个猫抓老鼠的方法public void catchMouse(){System.out.println("抓老鼠--cat");}
    }
    -----------------------------------------------------------------------------package com.kgc02;public class Test01 {public static void main(String[] args) {//创建一个猫类对象Cat cat = new Cat();//为猫类对象name属性进行赋值cat.name = "Tom";//为猫类对象age属性进行赋值cat.age = 1;//调用猫类方法cat.catchMouse();//调用毛类继承来的eat方法cat.eat();}
    }
    
  • 继承的特点 :

    • 成员变量
      • 私有化 private
        • 父类中的成员,无论是共有的还是私有的,均会被子类继承
        • 子类虽然会继承父类的成员,但子类不能对继承的私有的成员直接访问,可以通过继承的公有的方法进行访问
      • 成员变量不重名没有影响,如果重名会有影响,如果声明的是子类对象,那么重名的成员变量调用的就是子类的
      • 如果需要用父类的,使用super关键字,类似于this
        • super.父类成员变量名
    • 成员方法
      • 成员方法不重名
      • 成员方法重名----重写override
        • 如果子类,父类中出现重名的成员方法,这是访问是一种特殊情况,叫做方法的重写
      • 总结
        • 在父子类的继承关系中,创建子类对象,访问成员方法的规则
          • 创建的对象是谁,就优先用谁,如果没有则向上找
        • 注意事项
          • 无论成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类
        • 重写
          • 在继承关系中,方法的名称一样,参数列表也一样,也叫覆盖,覆写
          • 重载 : 方法的名称一样,参数列表不一样
          • 子类根据需要,定义特定自己的行为,即沿袭父类的功能名称,有根据子类的需要重新实现父类的方法,从而增强可扩展性
    • 总结
      • 父类
        • @Override 卸载方法前面,用来检测是否有效的正确的覆盖重写
      • 子类方法的返回值类型 必须小于等于父类方法的返回值类型(小于其实就是是它的子类)
        • java.lang.Object类是所有类的公共最高父类(祖宗类),java.lang.String 就是Object的子类
        • 如果返回值类型是基本数据类型和void,那么必须相同
      • 子类方法的权限必须大于等于父类方法的权限修饰符
        • public > protected > 缺省 > private
      • 几种特殊的方法不能重写
        • 静态方法不能重写
        • 私有在子类中不可见的方法不能 重写
        • final方法不能重写
    //声明父类:Person类 包含属性:姓名,年龄,性别 属性私有化,get/set 包含getinfo方法
    package com.kgc03;
    public class Person {private String name;private int age;private String gender;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getInfo(){return "姓名:"+name+"\t"+"年龄:"+age+"\t"+"性别:"+gender+"\t";}
    }
    //声明子类:Student类 继承Person类,新增属性score,属性私有化get/set 包含getinfo方法
    package com.kgc03;
    public class Student extends Person {private int score;public int getScore() {return score;}public void setScore(int score) {this.score = score;}@Overridepublic String getInfo() {return super.getInfo()+"成绩:"+getScore()+"\t";}
    }
    //声明子类:Teacher类 继承Person类,新增属性salary,属性私有化get/set 包含getinfo方法
    package com.kgc03;
    public class Teacher extends Person{private int salary;public int getSalary() {return salary;}public void setSalary(int salary) {this.salary = salary;}@Overridepublic String getInfo() {return super.getInfo()+"薪资:"+salary+"\t";}
    }
    //测试类
    package com.kgc03;public class Test03 {public static void main(String[] args) {Student st = new Student();st.setName("张三");st.setAge(18);st.setGender("男");st.setScore(100);System.out.println(st.getInfo());Teacher t = new Teacher();t.setName("李四");t.setAge(28);t.setGender("女");t.setSalary(10000);System.out.println(t.getInfo());}
    }
    
    • 构造方法
      • 构造方法的名字是与类名一致的,所以子类是无法继承父类构造方法的
      • 构造方法的作用,是初始化成员变量的,所以子类的初始化过程中必须先执行父类的初始化动作,子类的构造方法中默认有一个super(),所以调用父类的构造方法,父类成员变量初始化后才可以给子类使用

11. 静态

  • static

    • 是一个成员修饰符,可以修饰类的成员,成员变量,成员方法

    • 被修饰的成员是属于类的,而不是单单属于某个对象,可以不用靠创建对象来使用

    • 静态方法

      • 可以叫类方法,也可以叫静态方法
      • 语法
      [其他修饰符] static 返回值类型 方法名([参数列表]){//方法体
      }
      
      • 在本类中,静态的方法可以直接访问,静态方法和静态变量
      • 在其他类中,可以使用 类名.方法 进行调用,也可以使用 对象名.方法 ,(推荐使用类名.方法名)
      • 在静态方法中不能出现this,也不能直接使用本类的非静态成员,相反,非静态的实例成员方法可以直接使用访问静态的类变量和静态方法
      • this,非静态的成员,这些都需要创建对象时才能使用,而静态方法调用时可以没有对象,也就是说静态方法只能访问静态变量
      package com.kgc01;public class Demo01 {public static void main(String[] args) {Son s = new Son();s.fun();  //有警告,没错误也可以运行 Son.fun();  //建议使用 类名.方法名//Son.method();     非静态不能使用s.method();}
      }
      class Son{private int a;private static int b;public static void fun(){
      //        静态方法只能访问静态变量----否则报错
      //        System.out.println(a);
      //        System.out.println(this.a);
      //        method();System.out.println(b);System.out.println("Son:fun()");}public void  method(){System.out.println("Son:method()");}
      }
      
    • 静态变量

      • 也叫类变量,静态变量
      • 类变量的值和类信息一起存在于方法区中
      • 它的get/set也是static的
      • 在static方法中如果有局部变量与类变量重名,使用 '类名.成员变量’进行区分
      • 静态变量是成员变量的一种,静态变量存储在方法区中,则它在类加载时就会进行初始化,所以静态变量访问的时候不需要创建实例(对象),直接可以通过类名来访问
      package com.kgc01;
      public class Demo02 {public static void main(String[] args) {//无需创建对象//静态变量是成员变量的一种,静态变量存储在方法区中,则它在类加载时就会进行初始化Chinese c1 = new Chinese("小红");Chinese c2 = new Chinese("小明");System.out.println("国家:"+c1.getCountry()+",姓名:"+c1.getName());System.out.println("国家:"+c2.getCountry()+",姓名:"+c2.getName());c1.setCountry("中国");    //两个对象共享,一个对象修改,会影响另一个对象System.out.println("国家:"+c1.getCountry()+",姓名:"+c1.getName());System.out.println("国家:"+c2.getCountry()+",姓名:"+c2.getName());// 所以静态变量访问的时候不需要创建实例(对象),直接可以通过类名来访问Chinese.setCountry("China");    //通过类名. 访问可读性更好System.out.println("国家:"+Chinese.getCountry()+",姓名:"+c1.getName());System.out.println("国家:"+Chinese.getCountry()+",姓名:"+c2.getName());}
      }
      class Chinese{//静态成员属于整个类所有,类的所有对象所共享private static String country="中华人民共和国";//非静态不会被共享private String name;public Chinese(String name) {this.name = name;}public static String getCountry() {return country;}public static void setCountry(String country) {Chinese.country = country;}public String getName() {return name;}public void setName(String name) {this.name = name;}
      }
      

12. 抽象类

  • 抽象类

    • 抽象 : 即不具体,或无法具体

    • 抽象方法 : 没有方法体的方法

    • 抽象类 : 被abstract修饰的抽象类

      • 抽象类
      [权限修饰符] abstract class 类名{}//父类
      [权限修饰符] abstract class 类名 extends 父类{}
      
      • 抽象方法
      [其他修饰符] abstract 返回值类型 方法名 ([形参列表]); //注意:抽象方法没有方法体
      
    • 继承抽象类的子类,必须重写父类的抽象方法,否则该子类也必须声明为抽象类,最终必须有子类实现该父类的抽象方法,否则,从最初的的父类到最终的子类都不能创建对象,失去意义

      package com.kgc01;
      abstract class Animal{public abstract void run();
      }
      class Cat extends Animal{@Override//重写----实现父类没有实现的方法public void run() {System.out.println("小猫在墙上走");}
      }
      public class Demo03 {public static void main(String[] args) {//创建子类对象Cat cat = new Cat();//调用run方法cat.run();}
      }
      
    • 注意事项

      • 抽象类不能创建对象,如果创建编译无法通过而报错,只能创建非抽象子类的对象
      • 抽象类中可以有构造方法,是供子类创建对象时,初始化父类成员变量使用的
      • 抽象类中不一定包含抽象方法,担忧抽象方法的类必定是抽象类
      • 抽象类的子类,必须重写父类的所有抽象方法,否则编译无法通过,除非该子类也是抽象类
      package com.kgc01;
      abstract class Graphic{private String name;public Graphic(String name) {this.name = name;}public abstract double getArea();public abstract double getPerimeter();public String getInfo(){return "名称:"+name+"\t"+"面积:"+getArea()+"\t"+"周长:"+getPerimeter()+"\t";}
      }class Circle extends Graphic{private double radius;public Circle(String name, double radius) {super(name);this.radius = radius;}@Overridepublic double getArea() {return radius*radius*3.14;}@Overridepublic double getPerimeter() {return radius*6.28*100/100;}public String getInfo() {return super.getInfo()+"半径:"+radius+"\t";}
      }class Rectange extends Graphic{public double length;public double width;public Rectange(String name, double length, double width) {super(name);this.length = length;this.width = width;}@Overridepublic double getArea() {return length*width;}@Overridepublic double getPerimeter() {return 2*(length+width);}public String getInfo() {return super.getInfo()+"长:"+length+"\t"+"宽:"+width+"\t";}
      }public class Demo04 {public static void main(String[] args) {Rectange rec = new Rectange("长方形",10,20);System.out.println(rec.getInfo());Circle cir = new Circle("圆",10);System.out.println(cir.getInfo());}
      }
      
      package com.kgc01;
      /*
      练习:
      1. 声明抽象父类: Person,包含抽象方法:1. public abstract void walk();2. public abstract void ea();
      2. 声明子类 Man, 继承 Person1. 重写walk(): 大步流星的走2. 重写eat(): 狼吞虎咽的吃饭3. 新增方法: public void smoke() 吞云吐雾
      3. 声明子类 Woman, 继承Person1. 重写walk(): 婀娜多姿的走2. 重写eat(): 细嚼慢咽的吃饭3. 新增方法: public void buy() 买买买
      4. 测试类中创建子类对象,调用 方法测试*/
      abstract class Person{public abstract void walk();public abstract void eat();
      }class Man extends Person{@Overridepublic void walk() {System.out.println("大步流星的走");}@Overridepublic void eat() {System.out.println("狼吞虎咽的吃饭");}public void smoke(){System.out.println("吞云吐雾");}
      }class Woman extends Person{@Overridepublic void walk() {System.out.println("婀娜多姿的走");}@Overridepublic void eat() {System.out.println("细嚼慢咽的吃饭");}public void buy(){System.out.println("买买买");}
      }public class Demo05 {public static void main(String[] args) {Man man = new Man();man.walk();man.eat();man.smoke();System.out.println("-----------------------");Woman woman = new Woman();woman.walk();woman.eat();woman.buy();}
      }
      

13. 多态

  • 多态

    • 多态是指同一行为,具有多个不同的表现形式

    • 前提

      • 继承父类或实现接口
      • 方法的重写
      • 父类引用指向子类对象
      父类类型 变量名 = new 子类对象;
      变量名.方法名();		//这个方法是父类中声明的,子类中重写的方法
      
    • 多态的体现

      • 编译时,看父类,只能调用父类声明的方法,不同的调用子类扩展的方法
      • 运行时,看子类,一定是执行子类重写的方法体
      package com.kgc02;
      abstract class Animal2{public abstract void eat();
      }class Cat extends Animal2{@Overridepublic void eat() {System.out.println("吃鱼");}public void catchMouse(){System.out.println("捉老鼠");}
      }class Dog extends Animal2{@Overridepublic void eat() {System.out.println("吃骨头");}
      }public class Demo01 {public static void main(String[] args) {//多态的形式创建对象Animal2 a1 = new Cat();//调用Cat中的eata1.eat();//a1.catchMouse();是子类的扩展的方法,父类中没有Animal2 a2 = new Dog();a2.eat();showAnimal2Eat(a1);showAnimal2Eat(a2);}//   public static void showCatEat(Cat a){
      //        a.eat();
      //    }public static void showAnimal2Eat(Animal2 b){b.eat();}
      }
      
    • 多态的好处

      • 多态参数
        • 在实际开发过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性和便利性
      • 多态数组
        • 家里养了两只猫,两条狗,想要统一管理他们的对象,可以使用多态数组
      package com.kgc02;public class Demo02 {public static void main(String[] args) {Animal2[] all = new Animal2[4];  //可以存储各种Animal子类对象all[0]=new Cat();all[1]=new Cat();all[2]=new Dog();all[3]=new Dog();for (int i = 0; i < all.length; i++) {all[i].eat();}}
      }
      
      //练习
      //声明一个抽象父类Traffic,包含抽象方法 public abstract void driver()
      //声明子类Car,Bicycle,并重写dirver方法
      //在测试类main中,创建一个数组,有各种交通工具,遍历调用driver方法,模拟马路上跑的各种交通工具
      package com.kgc02;abstract class Traffic{public abstract void driver();
      }
      class Bicycle extends Traffic{@Overridepublic void driver() {System.out.println("自行车");}
      }
      class Car extends Traffic{@Overridepublic void driver() {System.out.println("汽车");}
      }
      public class Demo03 {public static void main(String[] args) {Traffic[] traffic = new Traffic[]{new Car(),new Car(),new Bicycle(),new Bicycle()};for (int i = 0; i < traffic.length; i++) {traffic[i].driver();}}
      }
      
    • 父子类之间的类型转换

      • 向上转型

        • 多态本身是子类类型向上转换的过程,这个过程是默认,父类的引用,指向子类的对象,这就是向上转型
      • 向下转型

        • 父类类型向子类类型向下转换的过程,这个过程是强制的
        子类类型 变量名 = (子类类型) 父类变量名;//向上转型
        Animal a = new Cat();   
        //向下转型 
        Cat c = (Cat) a;
        
    • instanceof

      • 为避免ClassCastException的发生,给引用变量做类型的校验,只要用instanceof判断返回为true,那么强制转换类型就是安全的,不会报错

        变量名/对象名 instanceof 数据类型;
        //如果属于就返回true,如果不属于就返回falseAniamls a = new Dog();
        if(a instanceof Cat){Cat cc = (Cat) a;cc.catchMouse();
        }else if(a instanceof Dog){Dog dd = (Dog) a;dd.watchHouse();
        }
        

14. Object类

  • 它是所有类的根类,即所有类的父类

  • toString() 默认情况返回的是对象进行时的类型,重写返回对象的详细信息来代替之前的getInfo

  • equals() 判断两个对象是否为同一个对象 和==类似

    package com.kgc03;public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object obj) {Person p = (Person) obj;if (this.name==p.name){return true;}else {return false;}}
    }
    
    //测试类
    public class Test01 {public static void main(String[] args) {Person p1 = new Person("小明",18);System.out.println(p1);System.out.println(p1.toString());Person p2 = new Person("小红",20);System.out.println(p1==p2);System.out.println(p1.equals(p2));Person p3 = p1;System.out.println(p1==p3);System.out.println(p1.equals(p3));}
    }
    

15. 接口

  • 接口 : java语言中一种引用类型,是方法的集合,主要是封装方法,它与定义类的方式相似 interface关键字,他也会被编译成class文件,但一定要明确它不是类,是另外一种数据类型(数组,类,接口)

  • Java里的接口, 就是抽象方法常量值的集合(简单理解为接口就是一种特殊的抽象类)

    [修饰符] interface 接口名 {//静态常量//抽象方法//默认方法//静态方法//私有方法
    }
    
  • 实现接口

    • 接口的使用,他不能创建对象,但是可以被实现( implements , 类似于被继承)
    • 类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类,实现的动作类似于继承,格式相似,只是关键字不同,实现用的是implements关键字
    [修饰符] class 实现类 implements 接口 {//重写接口中的抽象方法[必须],如果实现类是抽象类,name可以不重写//重写接口中默认方法[可选]
    }[修饰符] class 实现类 extends 父类 implements 接口 {//重写接口中的抽象方法[必须],如果实现类是抽象类,name可以不重写//重写接口中默认方法[可选]
    }
    
  • 非抽象类实现接口

    • 必须重写接口所有的抽象方法
    • 继承了接口的默认方法,即可以直接调用,也可以重写
      • 重写时,default关键字就不要再写了,它只用于接口中表示默认方法,到类中就没有默认方法这个概念了
      • 不能重写静态方法
    //练习
    //声明一个接口LiveAble//包含两个抽象方法 void eat();void breathe();//包含一个默认方法default void sleep(); 睡觉//包含静态方法 static void drink(); 喝水
    package com.kgc04;
    public interface LiveAble {public abstract void eat();public abstract void breathe();public default void sleep(){System.out.println("不动");}public static void drink(){System.out.println("喝水");}
    }package com.kgc04;
    public class Animal implements LiveAble{@Overridepublic void eat() {System.out.println("吃东西");}@Overridepublic void breathe() {System.out.println("吸入氧气,呼出二氧化碳");}@Overridepublic void sleep() {System.out.println("闭上眼睡觉");}
    }package com.kgc04;
    public class Plant implements LiveAble{@Overridepublic void eat() {System.out.println("吸收营养");}@Overridepublic void breathe() {System.out.println("吸入二氧化碳,呼出氧气");}
    }package com.kgc04;
    public class Test {public static void main(String[] args) {//创建实现类(子类) 对象Animal a = new Animal();a.eat();a.sleep();a.breathe();System.out.println("------------------------");//创建实现类 对象Plant p = new Plant();p.eat();p.sleep();p.breathe();System.out.println("------------------------");//通过接口名,调用静态方法LiveAble.drink();}
    }
    

16. 异常

  • 异常 : 指的是程序在执行过程中,出现的非正常的情况,如果不处理最终会导致JVM的非正常停止

  • 对于异常有两种解决方法,一种是遇到错误就终止程序的运行,另一种是由程序员在编写程序时就考虑到错误的检测,错误消息的提示,以及错误的处理

  • 异常的根类 : java.lang.Throwable,其子下有两个子类,java.lang.Error与java.lang.Exception,平时所说的异常指的是java.lang.Exception

    • Error : 严重错误,好比绝症
    • Excpetion : 表示异常,变成错误或偶然的外在因素导致的一般性问题,程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的,好比感冒
      • 下标越界,读的文件不存在等
  • Throwable 中常用的方法

    • public void printStatckTrace() : 打印异常的详细信息,包含异常的类型,异常的原因,出现的位置
    • public void getMessage() : 获取发生异常的原因,提示错误原因
  • Exception 异常的分类

    • 编译时异常 : checked 异常,在编译时检查,如果没有处理异常则编译失败
    • 运行时异常 : runtime 异常,在运行期间,检查异常,如下标越界,类型转换
  • java异常处理的5个关键字 : try catch finally , throw throws

    • try…catch 捕获异常

      • 是对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式的处理
      try{//可能出现异常的代码
      }catch(异常类型 e){//处理异常的代码//记录日志/打印异常信息/继续抛出异常
      }
      
      //例1
      package com.kgc01;
      import java.io.File;
      import java.io.FileNotFoundException;public class TestException {public static void main(String[] args) {File f = new File("d:\\a.txt");try{if (!f.exists()){throw new FileNotFoundException("d:\\a.txt"+"不存在");}}catch (FileNotFoundException e){System.out.println(e.getMessage());}}
      }
      
      //例2
      package com.kgc01;
      public class Test01 {public static void main(String[] args) {int[] arr = new int[2];//下标越界try{for (int i = 0; i <=arr.length ; i++) {System.out.println(arr[i]);}}catch (ArrayIndexOutOfBoundsException e){System.out.println(e);//出现错误的下标System.out.println(e.getStackTrace());//错误地址}}
      }
      
      //例3
      package com.kgc01;
      import java.util.Scanner;public class Test02 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.print("请输入一个整数:");//将可能出现错误的地方try起来(输入字符串)try{int a = sc.nextInt();System.out.println(a);}catch(Exception e){//捕获输出错误类型System.out.println(e);}//不影响程序的运行System.out.println("正常运行");}
      }
      //注:Exception是所有错误的父类,不知道错误类型可以使用Exception
      
  • throws 抛出异常,交给上级处理,如果都不处理,最终会交给JVM

    • package com.kgc01;import java.util.InputMismatchException;
      import java.util.Scanner;public class Test03 {public static void main(String[] args) {try{getInt();}catch (ArrayIndexOutOfBoundsException e){System.out.println("请输入一个整数");}}public static void getInt() throws InputMismatchException{Scanner sc = new Scanner(System.in);System.out.print("请输入一个整数:");int a = sc.nextInt();System.out.println(a);System.out.println("正常运行");}
      }
      
  • finally

    • 有一些特定的代码,不论是否出现异常,都要执行的代码

      try{//代码
      }catch(){//代码
      }finally{//代码
      }
      
      package com.kgc01;import java.util.InputMismatchException;
      import java.util.Scanner;public class Test03 {public static void main(String[] args) {try{getInt();}catch (InputMismatchException e){System.out.println("请输入一个整数");}finally {System.out.println("欢迎下次光临");}}public static void getInt() throws InputMismatchException{Scanner sc = new Scanner(System.in);System.out.print("请输入一个整数:");int a = sc.nextInt();System.out.println(a);System.out.println("正常运行");}
      }
      
  • 异常处理

    • 一次性处理
      • catch后写所有异常的父类 Exception
    • 分开处理
      • 多个catch,各自处理各自的异常
    • 不处理
      • throws抛出异常,交给上级处理

17. QuickHit

需求概述:
根据输入速率和正确率将玩家分为不同级别
级别越高,一次显示的字符数越多,玩家正确输入一次的得分也越高
规定时间内完成规定次数的输入,正确率达到规定要求,则升级
玩家最高级别为6级、初始级别一律为1级
用户错误输入一次,游戏结束

核心代码

package com.kgc;
//生成随机的字符串
import java.util.Random;
import java.util.Scanner;public class QuickHit {public static void main(String[] args) {//创建random随机对象Random random = new Random();//可改变长度的字符串StringBuffer buffer = new StringBuffer();for (int i = 0; i < 1; i++) {           //控制字符串的长度//产生一个随机数int rand = random.nextInt(4);//控制字符串的难易程度//根据随机数拼接字符串switch (rand){case 0:buffer.append(">");break;case 1:buffer.append("<");break;case 2:buffer.append("*");break;case 3:buffer.append("&");break;}System.out.println("buffer="+buffer);Scanner sc = new Scanner(System.in);System.out.print("请输入:");//输入前开始计时(从19700101 00:00:00开始)long l1 = System.currentTimeMillis();String in = sc.next();//输入后结束计时long l2 = System.currentTimeMillis();//打印时间差long l = (l2-l1)/1000;System.out.println("所用时长"+l+"秒");if (in.equals(buffer.toString())){System.out.println("相同");}else {System.out.println("不相同");}}}
}

游戏项目

  • 测试类
    • 创建一个玩家
    • 调用play方法
public class Test {public static void main(String[] args) {//创建一个玩家Player player = new Player();player.play();}
}
  • 玩家级别类
    • 属性 : 级别编号,各级别一次输出字符串的长度,各级别输出字符串的次数,各级别闯关的时间限制,各级别成功输入一次字符串之后增加的分值
    • 构造方法(全参),get/set
public class Leavel {private int leavelNo;//级别号private int strLength;//各级别一次输出字符串的长度private int strTimes;//各级别输入字符串的次数private int timeLimit;//各级别闯关的时间限制private int perScore;//各级别成功输入一次的字符串后增加的分值public Leavel(int leavelNo, int strLength, int strTimes, int timeLimit, int perScore) {this.leavelNo = leavelNo;this.strLength = strLength;this.strTimes = strTimes;this.timeLimit = timeLimit;this.perScore = perScore;}public int getLeavelNo() {return leavelNo;}public void setLeavelNo(int leavelNo) {this.leavelNo = leavelNo;}public int getStrLength() {return strLength;}public void setStrLength(int strLength) {this.strLength = strLength;}public int getStrTimes() {return strTimes;}public void setStrTimes(int strTimes) {this.strTimes = strTimes;}public int getTimeLimit() {return timeLimit;}public void setTimeLimit(int timeLimit) {this.timeLimit = timeLimit;}public int getPerScore() {return perScore;}public void setPerScore(int perScore) {this.perScore = perScore;}
}
  • 配置级别类
    • 不可更改的,静态的,定义一个级别的数组,数组的长度是6
    • 配置没有人调用,所以需要放到静态代码块里
public class LevelParam {public final static Level[] levels = new Level[6];  //对应6个级别,不可修改的,加载类时同时加载static {levels[0] = new Level(1,1,6,30,1);levels[1] = new Level(2,2,5,25,2);levels[2] = new Level(3,3,4,20,3);levels[3] = new Level(4,4,3,15,5);levels[4] = new Level(5,5,2,10,8);levels[5] = new Level(6,6,1,5,20);}
}
  • 玩家类
    • 属性 级别号,当前积分,级别的开始时间,级别的使用时间
import java.util.Scanner;
public class Player {private int levelNo;//级别private int curScore;//当前积分private long startTime=0;//各级别开始时间private int usedTime;//各级别已经用的时间public int getLevelNo() {return levelNo;}public long getStartTime() {return startTime;}public void setStartTime(long startTime) {this.startTime = startTime;}public void setLevelNo(int levelNo) {this.levelNo = levelNo;}public int getCurScore() {return curScore;}public void setCurScore(int curScore) {this.curScore = curScore;}public int getUsedTime() {return usedTime;}public void setUsedTime(int usedTime) {this.usedTime = usedTime;}public void play(){Game game = new Game(this);Scanner sc = new Scanner(System.in);//外层 循环控制级别for (int i = 0; i < LevelParam.levels.length; i++) {//1.晋级levelNo+=1;//2.晋级后计时清零,积分清零startTime = System.currentTimeMillis();curScore=0;//内层 循环控制循环次数//3.控制一个级别玩的次数for (int j = 0; j < LevelParam.levels[levelNo-1].getStrTimes(); j++) {//3.1 游戏输出字符串String outStr = game.printStr();//3.2 接收用户输入String inStr = sc.next();//3.3 游戏中判断玩家输入的是否正确并输出相应的结果信息game.printResult(outStr,inStr);}}}}
  • 游戏类
    • 属性 : 玩家
    • 构造方法
    • printStr() 打印随机字符串的结果并返回,printResult(输出的结果,用户输入的字符串) 打印结果信息
import java.util.Random;//游戏类
public class Game {public Player player;//构造方法,传入玩家public Game(Player player) {this.player = player;}//输出指定级别,规定长度的字符串public String printStr(){int strLength = LevelParam.levels[player.getLevelNo()-1].getStrLength();  //取到对应玩家的长度StringBuffer buffer = new StringBuffer();Random random = new Random();//通过循环生成 要输出的字符串//外循环控制字符串的长度for (int i = 0; i < strLength; i++) {//产生随机数int rand = random.nextInt(strLength);//根据随机数拼接字符串switch(rand){case 0:buffer.append(">");break;case 1:buffer.append("<");break;case 2:buffer.append("*");break;case 3:buffer.append("&");break;case 4:buffer.append("%");break;case 5:buffer.append("#");break;}}//输出字符串System.out.println(buffer);//返回字符串return buffer.toString();}//判断玩家输入是否正确,并输出相应的结果信息public void printResult(String out,String in){//判断是否输入正确boolean flag;if(out.equals(in)){flag=true;}else {flag=false;}//如果输入正确if (flag){long currenttime=System.currentTimeMillis();  //获取当前时间的毫秒// 判断是否超时// 已用时long yys=(currenttime-player.getStartTime())/1000;//System.out.println(yys);// 级别时间long jbsj=LevelParam.levels[player.getLevelNo()-1].getTimeLimit();if (yys>jbsj) {System.out.println("太慢了");System.exit(1);  // 系统退出}else{//如果没有超时//取出之前的积分+过一次给的分数int jf = player.getCurScore()+LevelParam.levels[player.getLevelNo()-1].getPerScore();//计算积分player.setCurScore(jf);//计算已用时player.setUsedTime((int)yys);System.out.println("输入正确,您的级别是:"+player.getLevelNo()+"\t"+"您的积分是:"+player.getCurScore()+"\t"+"已用时间:"+player.getUsedTime());//判断用户是否已经闯关到最后一关if(player.getLevelNo()==6){//取出当前积分和,最后一关玩的次数*每次的分数,如果相等就通关了int dqjf= player.getCurScore();int tgf = LevelParam.levels[player.getLevelNo()-1].getStrTimes()*LevelParam.levels[player.getLevelNo()-1].getPerScore();if (dqjf==tgf){System.out.println("恭喜通关!");System.exit(0);}}}}else {System.out.println("错误,退出");System.exit(1);}}
}

相关内容

热门资讯

原创 汪... 文:金玉 编辑:宇铭 汪小菲带孩子逛宝岛当地动物园的画面十分的温馨,很多粉丝在为汪小菲一家人送上祝...
进入暑期,北京警方处理涉旅违法... 据新京报讯(记者张静姝 实习生张启扬)新京报记者获悉,6月18日进入暑期以来,北京警方共处理涉旅违法...
我是长沙人,去了趟广东广州,有... 作为一个在长沙嗦粉长大的弗兰人,这次专门抽空去广州玩了趟大的!哎呀,以前总听讲“食在广州”,这次算是...
求一个电影名,关于幽灵船的,记... 求一个电影名,关于幽灵船的,记得剧情!给20。应该算多的吧- -跪谢!!!你去看看是不是《恐怖游轮》...
如何促进和猫咪的感情 如何促进和猫咪的感情多陪伴是增进感情的关键。需要注意的是有一定的技巧,比如不要用肢体去逗猫,猫咪会把...
好看的女生小说推荐 好看的女生小说推荐言情:唐七公子的三生三世系列、华胥引,十年一品温如言穿越:十一处特工皇妃、凤囚凰现...
元末明初算明朝还是元朝 元末明初算明朝还是元朝急需!!!元末明初是一个精确表达的时段,既不能说是明朝,又不能说是元朝
画眉鸟一般几月换毛 画眉鸟一般几月换毛每年的阴历七月份开始九月份结束
轮毂改大可以备案吗 轮毂改大可以备案吗汽车更改轮毂需要备案,如果轮毂尺寸不改可以不备案。轮毂是轮胎内廓轮钢通过立柱连接的...
多多支付怎么解绑银行卡 多多支付怎么解绑银行卡点击拼多多,点右下角个人中心。再点多多钱包。点右上角更多。点银行卡。可以看到你...
徐凤年死士都是谁? 徐凤年死士都是谁?在原著中,其实徐凤年身边有七个死士,首先是徐骁留的五个,分别是用天干来排序的,分别...
魔兽DOTA里的白牛怎么用(详... 魔兽DOTA里的白牛怎么用(详细步骤)其实很好用,补刀会吧,动腿,加攻装备(你想出什么随便),加个振...
春节二年级作文 春节二年级作文   在平凡的学习、工作、生活中,大家一定都接触过作文吧,作文是人们把记忆中所存储的有...
化学的历史由来 化学的历史由来 化学的历史渊源非常古老,可以说从人类学会使用火,就开始了最早的化学实践活动。 我们...
你只要不说自己的事,别人就不会... 你只要不说自己的事,别人就不会知道你的事对吗?有可能,但是富于观察力的人可能会从你细微的动作,神态,...
很痛苦,很讨厌作为人活着 很痛苦,很讨厌作为人活着虽然这些现象是人的一种本能,但是也是可以通过一些办法改变的。第一,有选择的接...
推荐唯美的绘本书 推荐唯美的绘本书介绍唯美一点的书,最好是单行本的,不是杂志的。 是那种文字和绘图结合的书 就像奇迹和...
怎样对付给你穿小鞋的人? 怎样对付给你穿小鞋的人? 你要是比较烈的性子,找到证据直接当场怼她要是不愿正面冲突,那就寻找机会...
SD高达模型阜阳哪有卖 SD高达模型阜阳哪有卖淘宝吧,一般5.8算
郭冬临版的程咬金片尾曲名字叫什... 郭冬临版的程咬金片尾曲名字叫什么?郭冬临版的程咬金片尾曲名字叫什么?程咬金的片尾曲叫《情与泪》,主唱...