小白学JAVA Day4(24-10-25)

方法的调用

静态方法    非静态方法

形参和实参

值传递和引用传递

this关键字

//学生类
public class Student { //注意类名应该与文件名相同,否则会报错
    //非静态方法
    public void say(){
        System.out.println("学生说话了");
    }

    //静态方法
    public static void say1(){
        System.out.println("学生没有说话");
    }
}
public class demo9 {
    //main方法
    public static void main(String[] args) {
        //静态类,可以直接调用
        Student.say1();//输出学生没有说话

        //通过实例化类new,来调用非静态方法,要创建对象
        //对象类型  对象名=对象值;
        Student student = new Student();//alt+ctrl补全
        student.say();//输出学生说话了

        //调用add方法,由于是非静态的,所以要实例化之后才能调用
        demo9 demo9 = new demo9();
        //实参要形参类型对应
        int c=demo9.add(1,2);//实参
        System.out.println(c);

        //值传递和引用传递
        int a=1;
        System.out.println(a);//输出1
        demo9.change(a);
        System.out.println(a);//输出1
        Person person = new Person();
        System.out.println(person.name);//输出null
        demo9.change2(person);
        System.out.println(person.name);//输出xiaoba

    }

    //修饰符  返回类型  方法名(参数){方法体}
    //return代表方法结束,当返回值为void时,为return;
    public String sayHello(){
        return "Hello";
    }

    //静态方法  static
    public static void a(){
        //b();//此处调用b()会报错,因为static表示和类一起加载的,类存在时就已经存在了
        //非静态表示在对象创建之后才存在,即类实例化之后才存在
    }
    //非静态方法
    public void b(){
    }

    //形参
    public int add(int a,int b){
        return a+b;
    }

    //值传递和引用传递
    public static void change(int a){ //返回值为空
        a=10;
    }
    public static void change2(Person person){
        person.name="xiaoba";
    }


}

//引用传递:对象,本质还是值传递
//定义了一个Person类,有一个属性name
class Person{
    String name;//默认值为null
}

类与对象的关系

类是一种抽象的数据类型,它是对某一类事物的整体描述/定义,但是不能代表某一个具体的事物

对象是抽象的具体实例

创建与初始化对象

使用new创建对象时,除了分配内存空间之外,还会对创建好的对象进行默认的初始化以及对类中构造器的调用

package oop;

public class Student2 {

    //属性
    String name;
    int age;

    //方法
    public void study(){
        System.out.println(this.name+"在学习");//this表示当前这个类
    }
}
package oop;

//一个项目应该只存在一个main方法,是唯一的入口
public class Application {
    public static void main(String[] args) {
        //实例化类,实例化之后会返回一个自己的对象
        //对象是该类的具体实例
        Student2 xiaoming = new Student2();
        Student2 xiaohong = new Student2();
        System.out.println(xiaoming.name);//会输出null,默认值
        System.out.println(xiaoming.age);//输出0
        xiaoming.name="小明";
        xiaoming.age=12;
        System.out.println(xiaoming.name);//输出小明
        System.out.println(xiaoming.age);//输出12
    }
}

类中的构造器也叫做构造方法,是在进行创建对象的时候必须要调用的

构造器必须和类的名字相同

必须没有返回类型,也不能写void

作用:1.new本质是在调用构造方法      2.初始化对象的值

注意点:在定义有参构造之后,如果想使用无参构造,要显式定义无参构造

package oop;

public class Person2 {

}
ckage oop;

//一个项目应该只存在一个main方法,是唯一的入口
public class Application {
    public static void main(String[] args) {
        /*//实例化类,实例化之后会返回一个自己的对象
        //对象是该类的具体实例
        Student2 xiaoming = new Student2();
        Student2 xiaohong = new Student2();
        System.out.println(xiaoming.name);//会输出null,默认值
        System.out.println(xiaoming.age);//输出0
        xiaoming.name="小明";
        xiaoming.age=12;
        System.out.println(xiaoming.name);//输出小明
        System.out.println(xiaoming.age);//输出12*/


        //实例化了一个对象
        Person2 person2 = new Person2();//此时在main中实例化一个对象,即使该类中什么都没有做
        //然后运行(注意一定要运行,不然不会出现Person2的.class文件),在项目结构中确认,打开out
        //文件夹中的的Person2的.class文件,可以发现Person2类里面有了一个同名的Person2的方法,且
        //该方法没有返回值---所以一个类即使什么都没有,也会存在一个 方法

    }

.class文件

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package oop;

public class Person2 {
    public Person2() {
    }
}
package oop;

public class Person2 {

    //显示定义构造器
    String name;
    //构造器的作用:1.实例化初始值
    public Person2(){ //无参构造
        this.name="xiaoba";
    }
    //2.使用new关键字,本质是在调用构造器(一旦定义了有参构造,无参构造必须显示定义,即必须写出代码)
    public Person2(String name){ //有参构造
        this.name=name;
    }
    //alt+insert生成构造器
}

package oop;

//一个项目应该只存在一个main方法,是唯一的入口
public class Application {
    public static void main(String[] args) {
        /*//实例化类,实例化之后会返回一个自己的对象
        //对象是该类的具体实例
        Student2 xiaoming = new Student2();
        Student2 xiaohong = new Student2();
        System.out.println(xiaoming.name);//会输出null,默认值
        System.out.println(xiaoming.age);//输出0
        xiaoming.name="小明";
        xiaoming.age=12;
        System.out.println(xiaoming.name);//输出小明
        System.out.println(xiaoming.age);//输出12*/


        //实例化了一个对象
        Person2 person2 = new Person2();//此时在main中实例化一个对象,即使该类中什么都没有做
        //然后运行(注意一定要运行,不然不会出现Person2的.class文件),在项目结构中确认,打开out
        //文件夹中的的Person2的.class文件,可以发现Person2类里面有了一个同名的Person2的方法,且
        //该方法没有返回值---所以一个类即使什么都没有,也会存在一个 方法
        System.out.println(person2.name);//输出xiaoba(若没有用构造器初始化,则会输出null)
        Person2 person3 = new Person2("xiaoming");
        System.out.println(person3.name);//输出xiaoming
    }
}

对象的属性  person.name

对象的方法  person.sleep( )

创建对象内存分析

 对象是通过引用来操作的,引用是指向对象的地址,从栈指向堆,真实操作的是堆,只是用的是栈里面一个简单的引用

类:静态的属性  属性

       动态的行为  方法 

封装

程序设计要追求:高内聚,低耦合

高内聚是类的内部数据操作细节自己完成,不允许外部干涉

低耦合是仅暴露少量的方法给外部使用

属性私有,get/set

封装的作用:1.提高程序的安全性,保护数据

                      2.隐藏代码的实现细节

                      3.统一接口

                      4.系统可维护性增加了

package oop;

public class Student3 {
    //属性私有
    //名字
    private String name;
    //学号
    private int id;
    //性别
    private char sex;
    //提供一些可以操作属性的方法
    //提供一些public的get/set方法
    //get获得这个数据
    public String getName(){
        return this.name;
    }
    //set给这个数据设置值
    public void setName(String name){
        this.name=name;
    }

    //用alt+Fn+insert自动生成构造函数
    public int getId() {
        return id;
    }
    public void setId(int id) {
        //在这里可以做安全性检查,判断用户输入的数据是否合理,如果不合理,就不会将它赋给私有属性
        this.id = id;
    }
}
package oop;

//一个项目应该只存在一个main方法,是唯一的入口
public class Application {
    public static void main(String[] args) {
        /*//实例化类,实例化之后会返回一个自己的对象
        //对象是该类的具体实例
        Student2 xiaoming = new Student2();
        Student2 xiaohong = new Student2();
        System.out.println(xiaoming.name);//会输出null,默认值
        System.out.println(xiaoming.age);//输出0
        xiaoming.name="小明";
        xiaoming.age=12;
        System.out.println(xiaoming.name);//输出小明
        System.out.println(xiaoming.age);//输出12*/


        //实例化了一个对象
        /*Person2 person2 = new Person2();//此时在main中实例化一个对象,即使该类中什么都没有做
        //然后运行(注意一定要运行,不然不会出现Person2的.class文件),在项目结构中确认,打开out
        //文件夹中的的Person2的.class文件,可以发现Person2类里面有了一个同名的Person2的方法,且
        //该方法没有返回值---所以一个类即使什么都没有,也会存在一个 方法
        System.out.println(person2.name);//输出xiaoba(若没有用构造器初始化,则会输出null)
        Person2 person3 = new Person2("xiaoming");
        System.out.println(person3.name);//输出xiaoming*/

        //封装
        Student3 student3 = new Student3();
        //student3.name报错,因为name是私有的
        student3.setName("xiaoba");
        String name3=student3.getName();
        System.out.println(name3);
        student3.setId(21);
        System.out.println(student3.getId());

    }
}

继承

继承的本质是对某一批类的抽象,从而实现对现实世界的更好的建模

Java中类只有单继承,没有多继承

子类是父类的扩展

继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖、组合、聚合等

object类

super

方法重写

super注意点:

1.super调用父类的构造方法,必须在构造方法的第一个

2.super必须只能出现在子类的方法或构造方法中(不能直接放在class中)

3.super和this不能同时调用构造方法

对比this:

代表的对象不同:this本身调用者这个对象

                             super代表父类对象的引用

前提不同:this没有继承也可以使用

                  super只能在继承条件下才可以使用

构造方法:this调用本类的构造

                  super调用父类的构造

package oop;

//父类
public class Person3 {
    public int money=1;
    public static void say(){
        System.out.println("说话");
    }

    private int house=2;//私有的无法被继承

    protected String name="wusaqi";

    public void print(){
        System.out.println("fulei");
    }
    //私有的无法被继承
    private void add(){
    }

    public Person3() {
        System.out.println("无参构造器");
    }
    //super.print();报错,因为super只能出现在子类的方法或构造方法中
}
package oop;

//学生 is 人  子类(派生类)
//注意继承和组合的区别,组合是在类中包含另一个类的对象
public class Student4 extends Person3{//学生继承了人的东西
    //子类继承父类,就会拥有父类的全部方法

    //ctrl+H显示继承的结构
    //在Java中,所有的类都默认直接或间接继承Object(可以省略)

    protected String name="jiyi";
    public void test(String name){
        System.out.println(name);//输出参数nam
        System.out.println(this.name);//输出jiyi
        System.out.println(super.name);//输出父类中的name,访问父类

        print();//调用子类
        this.print();//调用子类,this明确指出是自己的子类的
        super.print();//调用父类

        //super.add();add()为私有,不可被继承
    }

    public Student4() {
        System.out.println("子类的无参构造器");
    }

    public void print(){
        System.out.println("zilei");
    }
}
package oop;

//一个项目应该只存在一个main方法,是唯一的入口
public class Application {
    public static void main(String[] args) {
        /*//实例化类,实例化之后会返回一个自己的对象
        //对象是该类的具体实例
        Student2 xiaoming = new Student2();
        Student2 xiaohong = new Student2();
        System.out.println(xiaoming.name);//会输出null,默认值
        System.out.println(xiaoming.age);//输出0
        xiaoming.name="小明";
        xiaoming.age=12;
        System.out.println(xiaoming.name);//输出小明
        System.out.println(xiaoming.age);//输出12*/


        //实例化了一个对象
        /*Person2 person2 = new Person2();//此时在main中实例化一个对象,即使该类中什么都没有做
        //然后运行(注意一定要运行,不然不会出现Person2的.class文件),在项目结构中确认,打开out
        //文件夹中的的Person2的.class文件,可以发现Person2类里面有了一个同名的Person2的方法,且
        //该方法没有返回值---所以一个类即使什么都没有,也会存在一个 方法
        System.out.println(person2.name);//输出xiaoba(若没有用构造器初始化,则会输出null)
        Person2 person3 = new Person2("xiaoming");
        System.out.println(person3.name);//输出xiaoming*/

        /*//封装
        Student3 student3 = new Student3();
        //student3.name报错,因为name是私有的
        student3.setName("xiaoba");
        String name3=student3.getName();
        System.out.println(name3);
        student3.setId(21);
        System.out.println(student3.getId());*/

        //继承
        Student4 student4 = new Student4();
        student4.say();
        System.out.println(student4.money);//输出的是从父类中继承的
        //System.out.println(student4.house);报错,因为house在父类中是私有的

        student4.test("qqwe");

        //继承:无参构造器
        Student4 student5 = new Student4();
        //首先执行父类的无参构造器,然后执行子类的无参构造器,且若显式写出,要写调用父类的构造在子类的的前面

    }
}

重写

package oop;

public class B {
    public static void trying(){
        System.out.println("B--trying");
    }

    public void trying2(){
        System.out.println("B--trying2");
    }
}
package oop;

//重写都是方法的重写,和属性无关
public class A extends B{
    public static void trying(){
        System.out.println("A--trying");
    }

    public void trying2(){
        System.out.println("A--trying2");
    }
}
        //重写
        A a = new A();
        a.trying();//输出A--trying

        B b=new A();//父类的应用指向了子类
        b.trying();//输出B--trying
        //方法的调用只和左边,即定义的数据类型有关
        //静态和非静态方法区别很大
        //重写只和非静态有关,和静态方法无关,且重写只能是public
        A a2 = new A();
        a2.trying2();//输出A--trying2
        B b2=new A();//子类重写了父类的方法
        b2.trying2();//输出A--trying2

重写:需要有继承关系,子类重写父类的方法(只能重写方法,不能重写属性)

        1.方法名必须相同

        2.参数列表必须相同

        3.修饰符:范围可以扩大,但是不能缩小  public>protected>default> private

        4.可能会抛出异常:范围可以被缩小,但不能扩大  ClassNotFoundException-->Exception

重写:子类的方法和父类必须一致,方法体不同

alt+Fn+insert选中重写:override

为什么需要重写?

1.父类的功能,子类不一定需要,或者不一定满足,需要对一些方法进行重写

多态 

动态编译:可扩展性

即同一方法可以根据发送对象的不同而采用多种不同的行为方式

一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类或有关系的类)

多态注意事项:

1.多态是方法的多态,属性没有多态

2.父类和子类有联系,不能将一个String类型转换为一个Person类型,有父子之间的关系才能转换,类型转换异常ClassCastException

3.存在的条件:继承条件,方法需要重写,父类引用指向子类对象  father  f1=new son();

哪些方法不能被重写?

1.static方法,属于类,不属于实例

2.final修饰的,常量,无法改变

3.private修饰的,私有

//父类
public class Person3 {
    
    //多态
    public void run(){
        System.out.println("run");
    }
}
//学生 is 人  子类(派生类)
//注意继承和组合的区别,组合是在类中包含另一个类的对象
public class Student4 extends Person3{//学生继承了人的东西
    //子类继承父类,就会拥有父类的全部方法

    //ctrl+H显示继承的结构
    //在Java中,所有的类都默认直接或间接继承Object(可以省略)
    //多态

   /* @Override  //重写
    public void run() {
        System.out.println("son");
    }*/

    public void eat(){
        System.out.println("eat");
    }
}

        //多态
        //一个对象的实际类型是确定的,可以指向的引用类型不确定
        Student4 student6 = new Student4();
        Person3 student7 = new Student4();//父类的引用指向子类
        //Object student8 = new Student4();也可以
        //String student9=new Student4();会报错,有父子之间的关系才能转换,不是任意一个类型都可以随意转换
        student7.run();//当子类Student4中没有重写run时,输出run;当子类重写了父类的方法,会执行子类的方法
        student6.run();//输出son
        student6.eat();//输出eat
        //student7.eat();不能这样直接调用eat(),会报错,因为student7的类型为Person3,Person3中没有eat()方法
        //但当子类和父类都有的情况下,只要子类没有重写父类,就调用父类的;如果子类重写了父类,就调用子类
        //对象能执行哪些方法只要看对象左边的类型,和右边关系不大
        //父类型的student7虽然可以指向子类,但是不能调用父类独有的方法
        ((Student4)student7).eat();//将students7强制转换为Students类型,高转低

父类引用指向子类的对象,子类的引用不能指向父类的对象

把子类转换为父类,向上转型,不用强制转换,可以直接转换过去

把父类转换为子类,向下转型,需要强制转换

方便方法的调用,可以使代码变得简洁

public class Student4 extends Person3{//学生继承了人的东西


    //intanceof
    public void go(){
        System.out.println("go");
    }
}
        //instanceof
        //Object>Person>Student4
        //Object>Person>Teacher
        //Object>String
        Object o=new Student4();//#注意会调用父类和子类的构造函数
        System.out.println(o instanceof Student4);//true
        System.out.println(o instanceof Person3);//true
        System.out.println(o instanceof Object);//true
        System.out.println(o instanceof Teacher);//false
        System.out.println(o instanceof String);//false

        Person3 person4=new Student4();
        System.out.println(person4 instanceof Student4);//true
        System.out.println(person4 instanceof Person3);//true
        System.out.println(person4 instanceof Object);//true
        System.out.println(person4 instanceof Teacher);//false
        //System.out.println(person4 instanceof String);编译就报错了,因为Person和String同级

        Student4 student8=new Student4();//#注意会调用父类和子类的构造函数
        System.out.println(student8 instanceof Student4);//true
        System.out.println(student8 instanceof Person3);//true
        System.out.println(student8 instanceof Object);//true
        //System.out.println(student8 instanceof Teacher);报错
        //System.out.println(student8 instanceof String);报错
public class Teacher extends Person3{

}

        //类型之间的转换:父  子
        //高               低
        Person3 q=new Student4();//new一个Student4(),直接变成Person3,低转高不需要强制转换,很自然地就转换过来了
        //q.go();报错,因为Person3里面没有go方法
        //将这个q转换为Student4类型
        Student4 w=(Student4)q;//高转低,通过强制类型转换
        w.go();//或者((Student4)q).go()
        //子类转换为父类,可能丢失自己本来的一些方法

今日总结

晚上不想学了,导致没有完成任务(哭)

今天学习的内容要好好理解,明天好好整理一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值