一、基础概念

标识符

  • 什么是标识符
    就是程序员在定义java程序时,自定义的一些名字,例如helloworld
    程序里关键字class
    后跟的Demo,就是我们定义的类名。类名就属于标识符的一种。标识符除了应用在类名上,还可以用在变量、函数名、包名上

  • 标识符必须遵循以下规则

    1. 标识符由26个英文字符大小写(azAZ)、数字(0~9)、下划线(_)和美元符号($)组成。
    2. 不能以数字开头,不能是关键字
    3. 严格区分大小写
    4. 标识符的可以为任意长度
  • 作用:给对应的对象进行初始化
  • 格式;

  1.关键字this是指:哪个对象调用this所在的函数。this就指向当前这个对象。

this关键字

  • this关键字代表了所属函数的调用者对象
  • this关键字作用
    1. 如果存在同名成员变量与局部变量时,
      在方法内部默认是访问局部变量的数据,
      可以通过this关键字指定访问成员变量的数据
    2. 在一个构造函数中可以调用另外一个构造函数初始化对象
  • this关键字调用其他的构造函数要注意的事项
    1. this关键字调用其他的构造函数时,
      this关键字必须要位于构造函数中的第一个语句
    2. this关键字在构造函数中不能出现相互调用的情况, 因为是一个死循环
  • this关键字要注意事项
    1. 存在同名的成员变量与局部变量时,
      在方法的内部访问的是局部变量(java
      采取的是“就近原则”的机制访问的)
    2. 如果在一个方法中访问了一个变量, 该变量只存在成员变量的情况下,
      那么java编译器会在该变量的前面添加this关键字
  • this关键字调用其他的构造函数要注意的事项:
    1. this关键字调用其他的构造函数时,
      this关键字必须要位于构造函数中的第一个语句
    2. this关键字在构造函数中不能出现相互调用 的情况, 因为是一个死循环

class Student{

    int id;  //身份证
    String name;  //名字

    //目前情况:存在同名 的成员 变量与局部变量,在方法内部默认是使用局部变量的。
    public Student(int id,String name){  //一个函数的形式参数也是属于局部变量。
        this(name); //调用了本类的一个参数的构造方法
        //this(); //调用了本类无参的构造方法。
        this.id = id; // this.id = id 局部变量的id给成员变量的id赋值
        System.out.println("两个参数的构造方法被调用了...");
    }

    public Student(){
        System.out.println("无参的构造方法被调用了...");
    }

    public Student(String name){
        this.name = name;
        System.out.println("一个参数的构造方法被调用了...");
    }
}

class Demo
{
    public static void main(String[] args) 
    {
        Student s = new Student(110, "铁蛋");
        System.out.println("编号:"+ s.id +" 名字:" + s.name);
/*
        Student s2 = new Student("金胖子");
        System.out.println("名字:" + s2.name);
    */
    }
}

  2.用法:

static(静态)

  • static(静态\修饰符) :
    静态的成员变量只会在数据共享区中维护一份,而非静态成员变量的数据会在每个对象中都维护一份的

    1. static修饰成员变量 : 如果有数据需要被共享给所有对象使用时,
      那么就可以使用static修饰
    • 静态成员变量的访问方式:
      • 方式1 : 可以使用对象进行访问
        格式 : 对象.变量名
      • 方式二 : 可以使用类名进行访问
        格式 : 类名.变量名
    • 注意 :
      1.
      非静态的成员变量只能使用对象进行访问,不能使用类名进行访问。
      2.
      千万不要为了方便访问数据而使用static修饰成员变量,只有成员变量的数据是真正需要被共享的时候才使用static修饰。
    • static修饰成员变量的应用场景 :
      如果一个数据需要被所有对象共享使用的时候,这时候即可好实用static修饰
    1. static修饰成员函数 : (静态函数)
    • 访问方式:
      方式一:可以使用对象进行访问。
      对象.静态的函数名()
      方式二:可以使用类名进行访问。
      类名.静态函数名字。

        推荐使用是类名直接访问静态的成员。
      
    • 静态的成员变量与非静态的成员变量的区别:

      1. 作用上的区别:
        1. 静态的成员变量的作用共享一个 数据给所有的对象使用。
        2. 非 静态的成员变量的作用是描述一类事物的公共属性。
      2. 数量与存储位置上的区别:
        1. 静态成员变量是存储方法 区内存中,而且只会存在一份数据。
        2. 非静态的成员变量是存储在堆内存中,有n个对象就有n份数据。
      3. 生命周期的区别:
        1. 静态的成员变量数据是随着类的加载而存在,
          随着类文件的消失而消失
          2.非静态的成员数据是随着对象的创建而存在,
          随着对象被垃圾回收器回收而消失。
    • 静态函数要注意的事项:

      1. 静态函数是可以调用类名或者对象进行调用的,而非静态函数只能使用对象进行调用。
      2. 静态的函数可以直接访问静态的成员,但是不能直接访问非静态的成员。
        原因 : 静态函数是可以使用类名直接调用的,
        这时候可能还没有存在对象,
        而非静态的成员数据是随着对象的存在而存在的
      3. 非静态的函数是可以直接访问静态与非静态的成员
        原因 : 非静态函数只能由对象调用, 当对象存在的时候,
        静态数据老早就已经存在了,
        而非静态数据也随着对象的创建而存在了
      4. 静态函数不能出现this或者super关键字。
        原因 : 因为静态的函数是可以使用类名调用的,
        一旦使用类名调用这时候不存在对象,
        而this关键字是代表了一个函数 的调用者对象, 这时候产生了冲突
    • 静态的数据的生命周期:静态的成员变量数据是优先于对象存在的

  • static什么时候修饰一个函数?
    如果一个函数没有直接访问到非静态的成员时,那么就可以使用static修饰了(一般用于工具类型的方法)

  • 静态函数不能访问非静态的成员?
    静态函数只要存在有对象, 那么也可以访问非静态的数据,
    只是不能直接访问而已

修饰符 函数名{ 初始化的语句;}

    (1).this关键字可以解决:构造函数私有化问题。

super关键字

  • super关键字代表了父类空间的引用

  • super关键字的作用 :

    1. 子父类存在着同名的成员时,在子类中默认是访问子类的成员,可以通过super关键字指定访问父类的成员
    2. 创建子类对象时,默认会先调用父类无参的构造方法,可以通过super关键字指定调用父类的构造方法
  • super关键字调用父类构造方法要注意的事项:

    1. 如果在子类的构造方法上没有指定调用父类的构造方法,那么java编译器会在子类的构造方法上面加上super()语句
    2. super关键字调用父类的构造函数时,该语句必须要是子类构造函数中的第一个语句
    3. super与this关键字不能同时出现在同一个构造函数中调用其他的构造函数。因为两个语句都需要第一个语句
  • super关键字与this关键字的区别:

    1. 代表的事物不一致
      1. super关键字代表的是父类空间的引用
      2. this关键字代表的是所属函数的调用者对象
    2. 使用前提不一致
      1. super关键字必须要有继承关系才能使用
      2. this关键字不需要存在继承关系也可使用
    3. 调用构造函数的区别 :
      1. super关键字是调用父类的构造函数
      2. this关键字是调用本类的构造函数
  • 注意的细节:

        注意:构造函数只能被构造函数调用,不能直接被一般方法调用。

instanceof 关键字

  • instanceof关键字的作用:判断一个对象是否属于指定的类别。
  • instanceof关键字的使用前提:判断的对象与指定的类别必须要存在继承或者实现的关系(学习接口的时候就会理解)
  • instanceof关键字的使用格式:
    对象 instanceof 类别
  • instanceof关键字的作用:一般做强制类型转换之前都会使用该关键字先判断一下,然后在进行转换
  1. 没有返回值类型
  2. 构造函数的函数名必须要与类名一致
  3. 构造函数并不是由我们手动调用的,构造函数是在创建对应对象的时候由jvm主动调用的(每创建一个对象就会调用一次构造函数)
  4. 如果一个类没有显示添加一个构造函数,那么java编译器会为该类添加一个无参的构造函数
  5. 如果一个类已经显示添加一个构造函数,那么java编译器就不会再为该类添加一个无参的构造函数
  6. 构造函数是可以以函数重载的形式存在多个的

    (2).this关键字可以用于构造函数间的调用,可以访问本类中的其他构造函数。是为了初始化的复用。  

final(最终、修饰符)

  • final关键字的用法:
    1. final关键字修饰一个基本类型的变量时,该变量不能重新赋值,第一次的值为最终的
    2. fianl关键字修饰一个引用类型变量时,该变量不能重新指向新的对象
    3. final关键字修饰一个函数的时候,该函数不能被重写
    4. final关键字修饰一个类的时候,该类不能被继承
  • 常量 的修饰符一般为: public static final

//圆形
class Circle{

    double r; //半径
    public static final double pi = 3.14; //固定不变的
    public Circle(double r){
        this.r = r;
    }

    //计算面积
    public final void getArea(){
        System.out.println("圆形的面积是:"+r*r*pi);
    }
}

class Demo2 extends Circle
{
    public Demo2(double r){
        super(r);
    }

    public static void main(String[] args) 
    {
        /*
        final Circle c = new Circle(4.0);
        test(c);
        */  
        Demo2 c = new Demo2(4.0);
        c.getArea();
    }

    public static void test(Circle c){
        c = new Circle(5.0);  //c变量又重新指向了新的对象。
        c.getArea();
    }
}

给所有的对象进行统一的初始化

        注意:必须定义在构造函数的第一行!

抽象类 : abstract

  • 抽象类的应用场景:

    • 我们在描述一类事物的时候,发现该种事物确实存在着某种行为,
      但是这种行为目前是不具体的,那么我们可以抽取这种行为
      的声明,但是不去实现该种行为,这时候这种行为我们称作为抽象的行为,我们就需要使用抽象类
    • 目前存在的问题:

        1. 动物类的run方法描述的不正确
        1. 没有强制要子类一定要重写run方法
  • 抽象类的好处: 强制要求子类一定要实现指定的方法。

  • 抽象类要注意的细节 :

    1. 如果一个函数没有方法体,
      那么该函数必须要使用abstract修饰把函数修饰成抽象的函数
    2. 如果一个类出现了抽象的函数,那么该类也必须使用abstract修饰
    3. 如果一个非抽象类继承了抽象类,
      那么必须要把抽象类的所有抽象方法全部实现
    4. 抽象类可以存在非抽象方法, 也可以存在抽象的方法
    5. 抽象类可以不存在抽象方法的
    6. 抽象类是不能创建对象的
      疑问:为什么抽象类不能创建对象呢?
      因为抽象类是存在抽象方法的,如果能让抽象类创建对象的话,那么使用抽象的对象调用抽象方法是没有任何意义的
    7. 抽象类是存在构造函数的,其构造函数是提供给子类创建对象的时候初始化父类的属性的
  • abstract不能与以下关键字共同修饰一个方法:

    1. abstract不能与private共同修饰一个方法
    2. abstract 不能与static共同修饰一个方法
    3. abstract 不能与final共同修饰一个方法

//动物类--->抽象类
abstract class Animal{

    String name;
    String  color;
    public Animal(String  name,String color){
        this.name = name;
        this.color = color;
    }

    //非抽象的方法
    public void eat(){
        System.out.println(name+"吃粮食");
    }

    //移动...(该函数没有方法体, 所以必须使用abstract修饰该函数)
    public abstract void run();
}

//狗 是属于动物中一种 
class Dog extends Animal{
    public Dog(String name,String color){
        super(name,color);
    }
    public void run(){
        System.out.println(name+"四条腿跑得很快...");
    }
}

//鱼 是属于动物中一种
class Fish extends Animal{
    public Fish(String name,String color){
        super(name,color);
    }
    public void run(){
        System.out.println(name+"摇摇尾巴游啊游!");
    }
}

class Demo{

    public static void main(String[] args) 
    {
        /*
        Dog d = new Dog("牧羊犬","棕色");
        d.run();

        //创建一个鱼对象
        Fish f  = new Fish("锦鲤","金黄色");
        f.run();
        */
        Animal a = new Animal();
    }
}
  • 常量的命名规范:全部字母大写,单词与单词之间使用下划线分隔
  • 格式:

           不要出现互相调用,产生递归,容易栈溢出。

配置文件类

  • Properties(配置文件类): 主要用于生产配置文件与读取配置文件的信息。
  • Properties要注意的细节:
    1. 如果配置文件的信息一旦使用了中文,那么在使用store方法生成配置文件的时候只能使用字符流解决,如果使用字节流生成配置文件的话,默认使用的是iso8859-1码表进行编码存储,这时候会出现乱码。
    2. 如果Properties中的内容发生了变化,一定要重新使用Properties生成配置文件,否则配置文件信息不会发生变化。

public class Demo{
    public static void main(String[] args) throws IOException {
        creatProperties();
//      readProperties();
    }

    //读取配置文件爱你的信息 
    public static void readProperties() throws IOException{
        //创建Properties对象
        Properties properties = new Properties();
        //加载配置文件信息到Properties中
        properties.load(new FileReader("F:\\persons.properties"));
        //遍历
        Set<Entry<Object, Object>> entrys = properties.entrySet();
        for(Entry<Object, Object> entry  :entrys){
            System.out.println("键:"+ entry.getKey() +" 值:"+ entry.getValue());
        }
        //修改狗娃的密码
        //把修改后的Properties再生成一个配置文件
        properties.setProperty("狗娃", "007");
        properties.store(new FileWriter("F:\\persons.properties"), "hehe");
    }

    //保存配置文件文件的信息
    public static void creatProperties() throws IOException{
        //创建Properties
        Properties properties = new Properties();
        properties.setProperty("狗娃", "123");
        properties.setProperty("狗剩","234");
        properties.setProperty("铁蛋","345");
        // 遍历Properties
        /*Set<Entry<Object, Object>> entrys = properties.entrySet();
        for(Entry<Object, Object> entry  :entrys){
            System.out.println("键:"+ entry.getKey() +" 值:"+ entry.getValue());
        }*/

        //使用Properties生产配置文件。
        //properties.store(new FileOutputStream("F:\\persons.properties"), "haha"); //第一个参数是一个输出流对象,第二参数是使用一个字符串描述这个配置文件的信息。
        properties.store(new FileWriter("F:\\persons.properties"), "hehe");
    }
}

 需求: 使用properties实现本软件只能运行三次,超过了三次之后就提示购买正版,退jvm.

public class Demo1 {

    public static void main(String[] args) throws IOException {
        File file = new File("F:\\count.properties");
        if(!file.exists()){
            //如果配置文件不存在,则创建该配置文件
            file.createNewFile();
        }

        //创建Properties对象。
        Properties properties = new Properties();
        //把配置文件的信息加载到properties中
        properties.load(new FileInputStream(file));
        FileOutputStream fileOutputStream = new FileOutputStream(file);

        int count = 0; //定义该变量是用于保存软件的运行次数的。
        //读取配置文件的运行次数
        String value = properties.getProperty("count");
        if(value!=null){
            count = Integer.parseInt(value);
        }

        //判断使用的次数是否已经达到了三次,
        if(count==3){
            System.out.println("你已经超出了试用次数,请购买正版软件!!");
            System.exit(0);
        }

        count++;
        System.out.println("你已经使用了本软件第"+count+"次");
        properties.setProperty("count",count+"");
        //使用Properties生成一个配置文件
        properties.store(fileOutputStream,"runtime");

    }
}

    (3).this关键字用来区分局部变量和成员变量同名的情况。

{ 初始化语句;}

        注意:this关键字标识的成员变量。

类型:

二、代码实例 

  • 构造代码块
    • 位于成员位置上
  • 局部代码块
    • 位于方法之内
  • 静态代码块

 1 class Person
 2 {
 3     private String name;
 4     private int age;
 5     
 6     private Person()//构造函数私有化
 7     {
 8         System.out.println("新对象实例化") ;//被构造函数调用的构造函数语句
 9     }
10     
11     Person(String n)
12     {
13         this();// 调用本类中的调用构造函数语句。
14         name = n;
15     }
16     
17     Person(String name,int age)
18     {
19         this(name);//调用本类中的调用构造函数语句。
20         this.age = age;//this标识的成员变量。
21     }
22     
23     public void show1()
24     {
25         System.out.println("name="+name);
26     }
27     
28     public void show2()
29     {
30         System.out.println("name="+name+",age"+age);
31     }
32     
33     //传递一个Person对象,判断是否是同龄人。
34     public boolean equalsAge(Person pp)
35     {
36         return this.age == pp.age;
37     }
38 }
39 
40 class ThisDemo
41 {
42     public static void main(String[] args) 
43     {
44 
45         Person p1 = new Person("xiaoming");
46         p1.show1();
47         Person p2 = new Person("xiaofang",20);
48         p2.show2();
49         Person p3 = new Person("xiaohong",21);
50         p3.show2();
51         
52         //输出p3、p4是否为同龄人
53         boolean b = p2.equalsAge(p3);
54         System.out.println("Whether or not the age is equal:  "+b);
55     }
56     
57 }

注意细节

三、代码运行

  • 构造函数的代码是位于成员变量的显示初始化语句、构造代码块语句之后执行的
  • 成员变量的显示初始化语句与构造代码块的语句的先后执行顺序是按照当前代码的顺序执行的
  • 成员变量的初始化语句和构造代码块的代码其实是在构造函数中完成的

  图片 1

 

  • this关键字代表的是所属函数的调用着对象作用:

 

  1. 一个类存在着同名的成员变量与局部变量时,在方法内部默认是访问局部变量的数据,我们可以通过this关键字来访问成员变量
  2. this关键字可以在构造函数中调用其他的构造函数初始化对象使用。this关键字注意的细节:1.如果在一个函数中访问一个成员变量,而且没有存在同名的局部变量时,那么Java编译器会默认在变量的前面加this关键字2.this关键字调用其他构造函数时,this语句必须位于构造函数中的第一个语句3.this关键字调用构造函数的时候不能出现相互调用的情况,因为是一个死循环的调用方式
静态数据是优先与对象而存在的

成员变量使用static修饰,那么该数据会进行方法区内存中,而且只会存在一份数据

使用方法:

  • 只需要使用static关键字修饰该成员变量就可以将数据移动到数据共享区
  • static修饰成员变量:

    • 如果一个数据需要被所有对象共享使用的时候,那么即可使用static修饰成员变量

       String name;//非静态成员变量 static String county = “中国”;//静态成员变量
      

访问方式:

  1. 可以使用对象进行访问。格式:对象.静态属性名
  2. 可以使用类名进行访问,
    格式:类名.属性名推荐使用:类名进行访问注意细节1.静态的成员变量可以使用类名或者是对象进行访问2.非静态的成员变量只能使用对象进行访问,不能使用类名进行访问3.千万不能为了方便访问而使用static修饰一个成员变量,只有这个成员变量需要被共享的时候才使用static修饰
  • static修饰成员函数:访问方式:
  1. 可以使用对象进行访问。格式:类名.函数名();
  2. 可以使用类名进行访问。格式:类名.函数名();注意细节1.非静态的函数只能使用对象调用,不能使用类名调用2.静态函数可以直接访问静态的成员,但是不能直接访问非静态的成员原因:静态函数可以使用类名调用,而这时候对象可能还没有存在内存中,所以非静态数据也就不在内存中,所以不能访问。3..非静态函数可以直接访问静态以及非静态成员。原因:非静态函数必须要由对象调用,如果对象存在了静态数据以及非静态数据早就存在内存中了。4.静态函数不能出现this以及super关键字原因:因为静态函数可以使用类名直接调用,而这时候可能还没有对象存在,this又代表当前对象。

  1. 数量上的区别:1.非静态成员变量是在每个对象中都维护一份数据2.静态成员变量只会在方法中维护一份数据
  2. 调用的区别:1.非静态的成员变量只能使用对象进行访问2.静态的成员可以使用对象、类名进行访问
  3. 存储位置上的区别:1.非静态成员变量是存储在堆内存中2.静态成员变量是存储在方法中
  4. 生命周期的区别:1.非静态成员变量是随着对象的创建而存在,随着对象的消失而消失的。2.静态成员变量是随着类文件的加载而而存在,随着类文件的消失而消失的
  5. 作用上的区别:1.非静态成员变量的作用是用于描述一类事物的属性2.静态成员变量的作用是提供一个共享数据给所有对象使用的
  • 什么时候使用static修饰成员变量*当成员变量需要共享的时候*
  • 什么时候使用static修饰一个函数呢?*如果一个函数没有直接访问非静态成员,那么即可使用static修饰该函数(常用于工具类的方法:Arrays。。。)*

Author

发表评论

电子邮件地址不会被公开。 必填项已用*标注