JAVA学习笔记(1)

JAVA学习笔记(1),第1张

JAVA学习笔记(1) 1.构造方法

构造方法是一个比较特殊的方法,通过构造方法可以完成对象的创建,以及实例变量的初始化(注意:实例变量没有赋值时系统会默认赋值,是在对象创建的时候赋值,在构造方法执行的过程中完成初始化的)

无参构造方法虽然里面什么都没写,但是这个方法体里面进行的实例变量默认值初始化。

只要没有给变量赋值,系统都会赋默认值

public class Student{    
    int no;    
    String name;    
    int age;    
    public Student(){        
        System.out.println("!!!");    
    }    
    public Student(int i){
        no=i;    
    }
}

1.当一个类没有提供任何构造方法,系统会自动提供一个无参数的构造方法,该构造方法被称为:缺省构造器

2.当一个类中提供了构造方法,系统不会再提供无参构造方法

3.无参数构造方法,有参数构造方法都可以调用,支持方法重载,一个类中构造方法可以有多个。

方法重载特点:在同一个类中,方法名相同,参数列表不同。

构造方法通过new运算符调用

构造方法的语法结构:

[修饰符列表] 构造方法名(形式参数列表){

构造方法体

通常在构造方法体中给属性赋值,完成属性的初始化

}

注意:修饰符列表统一写public,不要写public static

构造方法名和类名必须一致

构造方法不需要指定返回值类型,也不能写void

普通方法的语法结构:

[修饰符列表] 返回值类型 方法名(形式参数列表){

方法体

}

public class Main{
    public static void main(String[] args){
        //调用普通方法 :类名.方法名
        Main.doSome();
        doSome();//在一个类里面可以省略类名
        //调用构造方法
        Student x=new Student();
    }
    public static void doSome(){
        System.out.println("do some!!");
    }
}
2.封装

作用:保证内部结构的安全性,屏蔽复杂、暴露安全

1.属性私有化

2.1个属性对外提供两个set和get方法,可以在set方法中设立关卡保证数据的安全性。

对外只提供接口

注意:java开发规范中有要求,set方法和get方法要满足以下格式。

public 返回值类型 get+属性名首字母大写(无参){

return xxx;

}

public void set+属性名首字母大写(有1个参数){

xxx = 参数;

}

public class Main{
    public static void main(String[] args){
        
    }
}
public class Person{
    //通过private关键字
    private int age;
    //对外提供简单的调用入口,set,get方法,并且这两个方法都是实例方法
    public int getAge(){
        return age;
    }
    public void setAge(int nianling){
        //在此位置上设置关卡
        if(nianling<0||nianling>150){
            System.out.println("对不起,年龄值不合法!");
            return;
        }
        age=nianling;
    }
}
3.static

对象被称为实例。

实例相关的有:实例变量、实例方法。

实例变量是对象变量,实例方法是对象方法。

实例相关的都需要先new对象,通过"引用."的方法去访问。

public class Main{
    public static void main(String[] args){
        //带有static的方法通过“类名.”的方式访问
        Main.doSome();
        //在同一个类中“类名"可以省略
        doSome();
        //需要先new出来,创建对象,然后访问
        Main mt=new Main();//Main类有一个无参构造方法
        mt.doOther();
    }
    public static void doSome(){
        System.out.println("do Some");
    }
    //这个方法没有static,这样的方法被称为:实例方法(对象方法,对象级别的方法)
    public void doOther(){
        
    }
}
//空指针异常
//本质原因:空引用访问“实例相关的数据”
//实例变量,实例方法
public class NullPointer{
    public static void main(String[] args){
        User u=new User();
        System.out.println(u.id);//0
        u.doSome();
        //引用变成null
        u=null;
        //id的访问需要对象的存在
        //System.out.println(u.id);//空指针异常
        //一个实例方法的调用也必须有对象的存在
        //u.doSome();//空指针异常
    }
}
class User{
    int id;
    //实例方法(对象相关的方法,对象级别的方法,对应对象级别的行为)
    public void doSome(){
        System.out.println("do Some");
    }
}

static翻译为“静态的”,所有static修饰的都是类相关的,类级别的。

所有static修饰的都是采用"类名."的方式访问

static修饰的变量:静态变量

static修饰的方法:静态方法

变量的分类:

方法体中声明的变量:局部变量

方法体外声明的变量:成员变量

成员变量分为

实例变量

静态变量

只要是方法不管是静态方法、实例方法、构造方法,它们在运行的时候都是需要压栈

堆里存实例变量,栈里存局部变量

静态变量是在类加载时初始化,存储在方法区

如果这个类型的所有对象的某个属性值都是一样的,不建议定义为实例变量,浪费内存空间,建议定义为类级别特征,定义为静态变量,在方法区中只保留一份,节省内存开销。

实例变量一定使用""引用.",静态的也可以但是不建议


class VarTest{
    //以下实例的都是对象相关的,访问时采用"引用.”的方式访问,需要先new对象
    //成员变量中的实例变量
    int i;
    //实例方法
    public void m1(){
        
    }
    //以下静态的,都是类相关的,访问时采用“类名.”的方式访问。不需要new对象
    //成员变量中的静态变量
    static int k;
    //静态方法
    public static void m2(){
        
    }
    
}

类=属性+方法

属性描述状态,方法描述行为动作

public class StaticTest02{
    public static void main(String[] args){
        Chinese c1=new Chinese("111","张三");
        Chinese c2=new Chinese();
        System.out.println(Chinese.country);
        System.out.println(c2.name);
        System.out.println(c1.idCard);
        //不会出现空指针异常
        c1=null;
        System.out.println(c1.country);
    }
}
class Chinese{
    String idCard;
    String name;
    static String country="中国";
    public Chinese(){
        //无参数
    }
    public Chinese(String num,String n){
        idCard=num;
        name=n;
    }
}

静态方法不能访问实例变量

如果方法中直接访问了实例变量,该方法必须是实例方法

工具类方法一般都是静态的

静态代码块

静态代码块在类加载时执行且只执行一次

在main方法执行之前执行,按照自上而下顺序执行

作用:1.不常用

2.特殊的时刻,类加载,记录日志

public class StaticTest06{
    static{
        System.out.println("A");
    }
    static{
        System.out.println("B");
    }
    //入口
    public static void main(String[] args){
        System.out.println("D");
    }
    static{
        System.out.println("C");
    }
}

实例代码块

实例语句块在类加载时不执行

只要是构造方法执行,在构造方法执行之前一定执行实例语句块

public class InstanceCode{
    //入口
    public static void main(String[] args){
        System.out.println("Main begin");
        new InstanceCode();
    }
    //实例语句块
    {
        System.out.println("实例语句块执行");
    }
    public InstanceCode(){
        System.out.println("无参数构成方法");
    }
    public InstanceCode(String name){
        System.out.println("有参数构成方法");
    }
}

4.执行顺序
public class Main{
    //静态变量在类加载时初始化,存在方法区
    static int i=100;
    //静态代码块在类加载时执行
    //只要时代码都存在方法区
    static{
        //可以访问i
        System.out.println("i="+i);
    }
    int k=111;//实例变量,在构造方法执行时内存空间才会开辟。
    static{
        //不能访问k
        System.out.println("k="+k);
    }
    //入口(main方法执行之前实际上执行了很多代码)
    public static void main(String[] args){
        
    }
}

1.对于一个方法来说,方法体中的代码有顺序,自上而下

2.静态代码块1和静态代码块2

3.静态代码块和静态变量

一个类体中的方法没有顺序

5.this

1.关键字

2.一个对象,一个this,this是一个变量一个引用,保存当前对象的内存地址,指向自身

  1. this存储在堆内存中对象内部

  2. this只能使用在实例方法中,谁调用这个实例方法,this就是谁。所以this代表的是:当前对象

  3. this.大部分情况下是可以省略的

    增强可读性且防止因为就近原则导致的误解

    参数名和实例变量重名,实例变量在该方法中使用this.方式访问

  4. 不能使用在静态方法中

public class ThisTest02{
    int i=100;
    static int k=111;
    public static void main(String[] args){
        //错误,无法从静态上下文中引用非静态变量
        //System.out.println(i);
        System.out.println(ThisTest02.k);
        System.out.println(k);
        ThisTest02 tt=new ThisTest02();
        System.out.println(tt.i);
    }
}
public class Last{
    public static void main(String[] args){
        Husband h1=new Husband("111","张三","1999-10-11",null);
        Wife w1=new Wife("222","李四","1989-11-10",h1);
        h1.wife=w1;
    }
}
class Husband{
    String idCard;
    String name;
    String birth;
    Wife wife;//引用类型
    public Husband(){
        
    }
    public Husband(String s1,String s2,String s3,Wife w){
        idCard=s1;
        name=s2;
        birth=s3;
        wife=w;
    }
}
class Wife{
    String idCard;
    String name;
    String birth;
    Husband husband;
    public wife(){
        
    }
    public Wife(String s1,String s2,String s3,Husband h){
        idCard=s1;
        name=s2;
        birth=s3;
        Husband=h;
    }
}

this除了可以使用在实例方法中,还可以使用在构造方法中

新语法:通过当前的构造方法去调用另一个本类的构造方法,可以使用以下语法格式.代码复用

需要注意的是:两个构造方法在同一个类中

且其只能出现在该构造方法中第一句,且只能出现一次

this(实际参数列表)

class Date{
    private int year;
    private int month;
    private int day;
    public Date(){
        this(1970,1,1);
    }
    public Date(int year,int month,int day){
        this.year=year;
        this.month=month;
        this.day=day;
    }
    public void setYear(int year){
        this.year=year;
    }
    public int getYear(){
        return year;
    }
    public void setMonth(int month){
        this.month=month;
    }
    public int getMonth(){
        return month;
    }
    public void setDay(int day){
        this.day=day;
    }
    public int getDay(){
        return day;
    }
}
6.继承extends

作用:代码复用,有了继承关系才有了后期的方法覆盖和多态机制。

缺点:耦合度高,父类修改,子类受到牵连

特性:①java中只支持单继承,不支持多继承

class E extends A,B{
}
//错误

②子类继承父类,除构造方法不能继承之外,剩下的都 可以继承。但是私有的属性无法在子类中直接访问。

③java中的类没有显示的继承任何类,则默认继承Object类,即一个类与生俱来就有Object类中所有的特征

System.out.println()

System是一个类名,直接使用System.out,说明out是一个静态变量

System.out返回一个对象,然后采用“对象."的方式访问println()方法

当输出一个引用的时候,println方法会自动调用引用的toString()方法,因此重写其很有必要

7.方法的覆盖Override和多态

方法覆盖

什么时候考虑方法覆盖Override:当子类继承父类之后,当继承过来的方法无法满足子类当前的业务需求时,子类有权对该方法重新编写,有必要进行”方法的覆盖"

什么时候考虑方法重载Overload:当一个类中如果功能相似,建议将名字定义一样

条件一:两个类必须要有继承关系

条件二:重写之后的方法和之前的方法具有:相同的返回值类型(对于返回值类型是基本数据类型时必须一样,引用数据类型变小可以,但意义不大,实际开发中没人这么写)、相同的方法名、相同的参数列表

条件三:访问权限(public>protected>private)不能更低,可以更高

条件四:重写之后的方法不能比之前的方法抛出更多的异常,可以更少

父类抛exception,子类可以抛也可也不抛也可以抛出范围更小的

注意事项:1.方法覆盖只是针对于方法与属性无关

2.私有方法无法覆盖

3.构造方法不能被继承,也不能被覆盖

4.方法覆盖只是针对于实例方法,静态方法覆盖没有意义

方法覆盖需要同多态机制联合起来才有意义

多态和对象有关系,而静态方法的执行不需要对象。

//静态方法不存在方法覆盖
​
public class OverrideTest05{
    public static void main(String[] args){
        Animal a=new Cat();
        //静态方法和对象没有关系
        a.doSome();//父类的方法,虽然使用"引用."来调,但是还是使用父类的方法
    }
}
class Animal{
    public static void doSome(){
        System.out.println("An");
    }
}
class Cat extends Animal{
    public static void doSome(){
        System.out.println("Ca");
    }
}

私有方法无法覆盖

方法覆盖的返回值类型

public class OverrideTest07{
    public static void main(String[] args){
        
    }
}
class Animal{
   
}
class Cat extends Animals{
    
}
class MyClass1{
    public Animal getAnimal(){
        return null;
    }
}
class MyClass2{
    public Cat getAnimal(){
        return null;
    }
}

多态

1.多态的基础语法

java中允许向上转型(子-》父)与向下转型(父-》子),要求必须有继承关系

多态指的是:父类型引用指向子类型对象。包括编译阶段和运行阶段

编译阶段:绑定父类的方法

运行阶段:动态绑定子类型对象的方法

分析程序一定要分析编译阶段的静态绑定和运行阶段的动态绑定。

只有编译通过的代码才能运行,没有编译轮不到运行。

什么时候使用向下转型:访问的方法是子类中特有的方法,此时必须使用向下转型

ClassCastException类型转换异常

运算符:instanceof

①可以在运行阶段动态判断指向引用的对象的类型

②语法:(引用 instanceof 类型)

③运算结果只能是:true/false

④假设c是一个引用,c变量保存了内存地址指向了堆中的对象

(c instanceof Cat)为true表示:c引用指向的堆内存的java对象是一个Cat

(c instanceof Cat)为false表示:c引用指向的堆内存的java对象不是一个Cat

if(a6 instanceof Cat){
    Cat y=(Cat)a6;
    y.catchMouse();
}

2.多态在开发中的作用

软件开发原则:最基本原则:开闭原则(ocp):对扩展开放,对修改关闭

面向父类型编程

降低程序的耦合度,提高程序的扩展力

面向抽象编程

public class Homework{
    public static void main(String[] args){
        //创建各种乐器对象
        Erhu erhu=new Erhu();
        Piano piano=new Piano();
        Violin violin=new Violin();
        Musician m=new Musician();
        m.play(erhu);
        m.play(piano);
        m.play(violin);
        //还可以
        m.play(new Erhu());
        m.play(new Piano());
        m.play(new Violin());
    }
}
//乐器父类
class Instrument{
    public void makeSound(){
        
    }
}
//乐手
class Musician{
    
    puclic void play(Instrument i){
        //编译阶段makeSound方法是Instrument的,运行阶段不一定是谁的
        i.makeSound();
    }
}
//子类
class Erhu extends Instrument{
    public void makeSound(){
        System.out.println("二胡的声音");
    }
}
//子类
class Piano extends Instrument{
    public void makeSound(){
        System.out.println("钢琴的声音");
    }
}
//子类
class Violin extends Instrument{
    public void makeSound(){
        System.out.println("小提琴的声音");
    }
}
super

1.this 能出现在实例方法中和构造方法中,不能使用在静态方法中

this.

this()只能出现在构造方法中,通过当前的构方法去调用“本类"中其他的构造方法,目的是:代码复用

2.super 能出现在实例方法中和构造方法中,不能使用在静态方法中

super.

super()只能出现在构造方法中,通过当前的构造方法去调用”父类“中的构造方法,目的时:创建子类对象的时候,先初始化父类特征。

当一个构造方法第一行,既没有this()又没有super()的话,默认会又一个super();表示通过当前子类的构造方法调用父类的无参数构造方法。所以必须保证父类的无参数构造方法是存在的。

注意:this(),super()不能共存

父类的构造方法一定会执行

在java语言中无论是构造什么方法,Object类的无参构造方法(处在栈顶)一定最先执行

class A{
    public A{
        
    }
    public A(int i){
        
    }
}
class B{
    public B(){
        //调用父类中有参数的构造方法
        super(100);
    }
}

在恰当的时间使用super(实际参数列表);

super代表“当前对象(this)”的父类型特征

注意:虽然在构造方法的执行过程中调用了父类的构造方法,父类的构造方法又向下继续调用其父类的构造方法,但是实际上对象只创建了一个

super用来创建当前父类型特征,super关键字代表的就是当前对象的那部分父类特征。

public class SuperTest04{
    public static void main(String[] args){
        Vip v=new Vip("张三");
        v.shopping();
    }
}
class Customer{
    String name;
    public Customer(){}
    public Customer(String name){
        super();
        this.name=name;
    }
}
class Vip extends Customer{
    public Vip(){}
    public Vip(String name){
        super(name);
    }
    //super和this都不能出现在静态方法中。
    public void shopping(){
        //this表示当前对象
        System.out.println(this.name+"正在购物!");
        //super表示的是当前对象的父类型特征
        System.out.println(super.name+"正在购物!");
        //同一
        System.out.println(name+"正在购物!");
    }
}

当父类和子类中有同名属性,想访问父类中的属性需要加super.

super不是引用,也不保存内存地址,也不指向任何对象

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5692999.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存