Java基础知识第三篇

注:部分代码演示如果因长度问题观看不便利,可粘贴到idea中观看

一、构造方法

1、概念

(1)构造方法又叫构造器,构造函数单词constructor

(2)构造方法就是用来创建对象的   

(3)每个类中都有构造方法,但是默认隐藏的

2、作用

(1)通过调用构造方法,可以在队中创建对象

(2)属性、方法初始化

3、无参构造

public 类名() {

}

例如:

    public Person () {

      

    }  //无参构造

}

public class Demo1 {

    public static void main(String[] args) {

        Person p1 = new Person();//创建对象

    }

}

1、每个类都有一个默认的无参构造方法。

2、构造方法没有返回值,也不需要定义返回值类型,连void也没有。

3、构造方法的方法名只能是当前类类名。

4、只能通过new来调用。

4、有参构造

有参构造就是给构造方法设计参数,调用构造方法时传入参数给属性赋值。

public 类名(数据类型 变量名){

this,成员属性 = 变量;
}

例如

class Student {

    public Student(String name, int age) {

        this.name = name;

        this.age = age;

    } //有参构造

}

public class Demo2 {

    public static void main(String[] args) {

        //对象的创建依赖构造方法出来的!!!

        Student stu = new Student("狗蛋", 12);

    }

}

1、一旦写了有参的构造方法,默认的无参构造方法就没了。

2、如果写了有参的构造方法但是没有传参会报错,想解决可以选择传参或者再写一个无参的放在那里。

  • 重载

重载是指方法中的重载,作用是方便调用,根据自己传入的参数决定执行哪个方法

class Person{

    String name;

   

    public void play () {

        System.out.println("玩耍");

    }

    public void play (String name) {

        System.out.println(name + "玩耍");

}

    /*public void play (String sb) {

        System.out.println(sb + "玩耍");

    } //只是修改了变量名

}

public class Demo1 {

    public static void main(String[] args) {

        Person p1 = new Person();

        p1.play();

        p1.play("狗蛋");

    }

}

  1. 方法的重载(overload): 在同一个类中,方法名一样, 参数列表不一样 叫方法的重载!!!
  2. 参数列表不同  : 参数列表不一样(类型,个数,顺序任意不一样都行)。
  3. 方法的重载和返回值无关,返回值是什么都不影响是否算是重载。
  4. 无参构造方法和有参构造方法之间也能叫方法的重载。

  • 封装(困难,需要多加练习)

面向对象的三个基本特征:封装,继承,多态

1、封装是什么

封装就是打包,将代码封装起来,有方法的封装和类的封装。作用是隐藏一些真实的细节,用户只需要使用即可。

1、类的封装

完整的封装步骤:

  1. 属性私有化,在前面设置private修饰符
  2. 提供set/get方法

class Person {

private String name;

private int age;

public void setName (String name) {

        this.name = name;

}

public String getName () {

        return this.name;

}

public void setAge (int age) {

        this.age = age;

}

public int getAge () {

        return this.age;

}

}

public class Demo1 {

    public static void main(String[] args) {

        Person p1 = new Person();

        p1.setName("张三");//赋值

        p1.setAge(12);

    System.out.println(p1.getName());//取值

    System.out.println(p1.getAge());

    }

}

1、为属性添加private方法后,使用alt+insert选中set and get 选项就可以全选将set/get方法自动导出。

2、set方法是为了赋值的,get方法是为了取值的。赋值和取值时在mian函数中进行。

四、继承

1、继承的概念

继承的关键词为extends,构成继承关系后子类能使用父类中的属性和方法。

注意:java中继承是单继承,类只能继承一个类,就是只有一个父类。    

public class 子类 extends 父类{

}

2、为什么要继承

(1)减少代码

(2)是形成多态的前提

3、继承入门代码

public class Animal {

    int age;

    String name;

    void eat(){

        System.out.println("吃" );

    }

}

动物类为父类,里面有两个属性一个方法。

public class Dog extends Animal{// 继承

}

狗类为子类

public class TestExtends{

    public static void main(String[] args) {

        Dog dog = new Dog( );

   

        dog.name = "大黄";

        dog.eat();

 Dog类继承Animal类,就可以父类属性和方法。

4、继承中的属性

(1)子类继承父类,就可以继承父类的属性。

(2)如果给父类设置私有属性,子类就无法使用父类的属性。

(3)假如子类和父类中有重名的属性,子类默认使用自己的(一般不会重复)。

5、继承中的方法

(1)继承中子类可以使用父类非私有方法。

(2)继承中,子类和父类中有一样的方法,默认调用自己的(即是重写)。

6、继承中的构造方法

(1)在创建子类对象时,会先创建父类对象再创建子类对象,因为子类构造方法里默认有super(); 也就是父类的无参构造方法并且在第一位。

五、重写

1、重写的概念

重写也可以叫做覆盖,它发生在继承中,子类重写父类的方法。当父类满足不了子类的需求了,子类才去重写父类的方法。

注意:重写只和方法有关

2、重写的特征

(1)访问修饰符一致

(2 )返回值类型一致

(3)方法名一致

(4)参数列表一致

总结:只有方法体的不同,其余一致。

3、重写入门代码

public class Father {

    public void eat () {

        System.out.println("吃窝窝头");

    }

}

父类写了eat方法,方法体为吃窝窝头。

public class Son extends Father{

    @Override

    public void eat() {

        System.out.println("吃白面馒头");

    }

}

子类重写了父类的eat方法,将方法体改为了吃白面馒头。

@Override只是告知程序员 这个方法 是重写的而已,是重写的严格限定。

public class Demo1 {

    public static void main(String[] args) {

        Son son = new Son();

        son.eat();

    }

}

结果为打印“吃白面馒头”。

      

六、this和super

1、概念      

this

super

作用

指代当前对象

指代父类对象

调用属性时

this.属性(自身属性)

super.属性(父类属性)

调用方法

this.方法(自身方法)

super.方法(父类方法)

调用构造方法

this()调用自身构造方法

super()调用父类·构造方法

使用位置

构造方法或者方法中

2、入门代码

public class Dog extends Animal{

    String name = "二哈";

    // 无参构造

    public Dog(){

        System.out.println("Dog()" );

    }

    @Override

    void eat() {

        System.out.println("狗吃骨头" );

    }

    public void show() {

        // 调用自己属性name

        System.out.println(this.name );

        // 调用父类属性name

        System.out.println(super.name );

        this.eat();//调用自己/父类方法

        super.eat();//调用父类方法

    }

}

      

七、访问权限修饰符

当前类中

同包不同类中

不同包但是是子类

不同包且不是子类

public

protected

默认

private

八、final

1、概念

final是一个修饰符,用来修饰类,属性和方法的。意思:最终的。

2、特点

(1)修饰类时,例如final class,类就不能再被继承,等于这个类绝后了。

(2)修饰变量(属性)时,例如final int a, 变量就成了常量需要立刻赋上初始值并且不能再修改。

(3)修饰方法时,方法不能被重写

(4)修饰对象的引用时,内存地址无法被修改

3、final入门代码

//1.使用final修饰的类无法被继承

//final class Person {

class Person {

    String name;

    //2.修饰属性(成员变量)  一定先赋值,一旦赋值无法更改

    final int age = 18;

    public void eat () {

        //3.修饰局部变量  变量可以先不赋值,但是使用的是否必须赋值,且赋完值以后无法修改

        final int a = 19;

       // a = 23;//会报错

        System.out.println(a);

    }

    //4.修饰方法, final修饰的方法不能被重写

     public final void sleep () {

        System.out.println("睡觉");

    }

}

class Man extends Person {

    /*public final void sleep () {

        System.out.println("睡觉");

    }*/ //报错

}

public class Demo1 {

    public static void main(String[] args) {

        //5.final修饰对象的引用

        final Person p1 = new Person();

        //p1.age = 23;

        System.out.println(p1);//1b6d3586

        Person p2 = new Person();

        System.out.println(p2);//4554617c

        //p1 = p2; 报错!!!

        System.out.println(p1);//4554617c

    }

}

九、static

1、概念

static的意思是静态的,是一修饰符。static修饰的属性和方法不在堆里,而是在方法区里且在内存只有一个,不管创建多少对象,该类静态属性和方法也只有一个,被该类的所有对象共享。             

2、加载时机

随着类的加载而加载,在栈和堆没出现之前就已经加载了并且在加载时就行了初始化

3、注意事项

static修饰的方法里不能使用this,因为你不可能指望一辆公交车只属于你一个人。

4、static入门代码

class Person{
    String name;
    int age;
    static String country; //被static修饰的属性会变斜体

    //static可以修饰方法,调用时 类.方法 就可以了
    public static void eat() {
        System.out.println("吃饭");
    }
}
public class Demo1 {
    public static void main(String[] args) {

        //静态属性和对象无关, 调用时 类.静态属性


        Person.country = "中国";
        System.out.println(Person.country);
        Person p1 = new Person();
        System.out.println(p1.country);//结果是中国,用对象调用也可以,但是不规范不推荐
        Person p2 = new Person();
        p2.country = "巴铁";
        System.out.println(p2.country);//结果是巴铁,static的属性是公用的,改变也是一起改变
        Person.country = "中国";
        System.out.println(p2.country);//结果是中国,static静态方法谁都可以用谁都可以改,公用的

        Person.eat();//
    }
}

5、总结

(1)static修饰属性时调用: 类.静态属性

(2)static修饰方法时调用: 类.静态方法

(3)static修饰代码块 :只要类加载(new的时候)就会执行静态代码块。 执行顺序:静态代码块》代码块》构造方法

6、使用场景

(1)场景1:当想要某个数据被对象共享时,就定义该属性为static,例如多个窗口对象共享火车票数据。

class TikectCounter {

    static int tikect = 100;

    public void sub () {

        tikect--;

    }

}

public class Demo5 {

    public static void main(String[] args) {

        TikectCounter tikectCounter1 = new TikectCounter();

       //每调用一次sub()方法就会让公共的票-1

        tikectCounter1.sub();

        System.out.println(tikectCounter1.tikect);

        TikectCounter tikectCounter2 = new TikectCounter();

        tikectCounter2.sub();

        System.out.println(tikectCounter2.tikect);

        TikectCounter tikectCounter3 = new TikectCounter();

        tikectCounter3.sub();

        System.out.println(tikectCounter3.tikect);

    }

}

十、多态

1、概念

多态,就是指方法的多种状态,换句话说多态就是同一个方法会表现出不同的状态。

2、多态的前提

(1)继承/实现(有父类子类关系)

(2)重写

(3)父类引用指向子类对象(向上转型)

3、多态入门例子

public class Animal {

    public void eat(){

        System.out.println("动物吃" );

    }

}

public class Dog extends Animal {// 多态条件1继承

    // 多态条件2重写

    @Override

    public void eat() {

        System.out.println("狗吃骨头" );

    }

}

public class TestPoly {

    public static void main(String[] args) {

        // 父类引用指向父类对象

        // Animal animal = new Animal();

        // 父类引用指向子类对象

        Animal animal = new Dog();

        animal.eat();// 编译看父类,运行看子类

        // eat方法是子类在执行

    }

}

4、多态的作用

减少耦合,提供扩展性

(1)现在有需求,设计方法传入一个狗类,执行出“狗吃骨头”。

(2)现在需求变了,想要表现出猫如何吃东西,该怎么办?

(3)假如,要展现动物园所有动物如何吃呢? 再假如后续又来了以前没有的动物,该如何表现吃的行为呢? 简单粗暴的想法,多定义几个方法..... 可以,但是很麻烦! 这些写,扩展性不好,来一个需要都需要改代码....

怎么办? 就需要多态!

只需要将方法的参数列表改变成父类即可,调用时传入想要表现的子类对象即可

5、多态使用注意事项

(1)父类里面的方法子类没有重写的话,无法体现多态。

(2)子类里面有特有方法,向上转型后父类方法也无法调用。

class Super {
    public void method() {
        System.out.println("method() in Super");
    }

    public void method(int i) {
        System.out.println("method(int) in Super");
    }
}

class Sub extends Super {
    public void method() {
        System.out.println("method() in Sub");
    }

    public void method(String str) {
        System.out.println("method(String) in Sub");
    }
}

public class Demo1 {
    public static void main(String args[]) {
        Super s = new Sub( );
        s.method(10);
        s.method( );
        //s.method("hello");// 报错,因为子类里特有的方法,父类无法调用,这也是重写的重要性
    }
}

十一、向上&向下转型

1、向上转型

父类引用指向子类对象Animal animal = new Dog();

将Dog类(子类)的对象包装的成Animal类(父类)。

向上转型后的注意事项:

(1)父类引用只能调用父类中有的方法(编译看父类)。

(2)真正执行看子类。

2、向下转型

向上转型是子类对象变父类对象,向下转型就是父类对象变子类对象,类似于Dog dog = (Dog) Animal();

                

向下转型想要成功,需要先向上转型再向下转型。成功以后就可以让父类对象变成子类对象来调用子类的方法。

向下转型例子

class Person {

    public void feed (Animal animal) {//在喂的方法中 去调用狗的看门方法 咋办?

        //即调用eat方法又调用lookdoor方法,要求上面的feed的参数必须Animal

        animal.eat();

        //animal 父类的引用。 只需要向下转型即可!!!

        Dog dog = (Dog) animal;

//在mian函数里向上转型过了,所以只需要一个向下转型

        dog.lookDoor();

    }

}

class Animal {

    public void eat () {

    }

}

class Dog extends Animal{

    @Override

    public void eat() {

        System.out.println("狗吃剩饭");

    }

    public void lookDoor () {

        System.out.println("狗能看家!!!");

    } //这个方法是狗类独有的,Animal类就可以通过向下转型调用

}

class Cat extends Animal {

    @Override

    public void eat() {

        System.out.println("猫吃老鼠");

    }

}

public class Demo1 {

    public static void main(String[] args) {

        Dog dog1 = new Dog();

        Person p1 = new Person();

        p1.feed(dog1); //子类给父类赋值等同于向上转型

    }

}

3、instanceof

语法格式 boolean 变量 = 对象 instanceof 类;

作用是测试左边的对象是否是右边类的实例。左边的对象是右边类或者子类创建的对象的时候返回true反之false。

举例:

class Animal {}

class Dog extends Animal {}

class Cat extends Animal{}

public class Demo1 {

    public static void main(String[] args) {

        Animal animal = new Animal();

        Dog dog = new Dog();

        Cat cat = new Cat();

        System.out.println(animal instanceof Animal); //true

        System.out.println(dog instanceof Animal); //true

        System.out.println(animal instanceof Dog);//false

        //规律: instanceof的左边的辈分比右边小 或者同类的平辈。才能是true

        //System.out.println(dog instanceof Cat);//false

        //开发中用的!!!

        Animal animal1 = new Dog();//向上转型

        System.out.println(animal1 instanceof Dog);//true

    }

}

拓展:

class Person {

public void feed (Animal animal) { //在喂的方法中 去调用狗的看门方法 咋办?

        //即调用eat方法又调用lookdoor方法,要求上面的feed的参数必须Animal

        animal.eat();

        //animal 父类的引用。 只需要向下转型即可!!!

        if (animal instanceof Dog) {

            Dog dog = (Dog) animal;// { //防止因为new Dog以外的导致报错,就利用instanceof只让类是Dog的运行

            dog.lookDoor();

        }

        if (animal instanceof Cat) {

            Cat cat = (Cat) animal;

            cat.sleep();

        }

    }

}

class Animal {

    public void eat () {

    }

}

class Dog extends Animal{

    @Override

    public void eat() {

        System.out.println("狗吃剩饭");

    }

    public void lookDoor () {

        System.out.println("狗能看家!!!");

    }

}

class Cat extends Animal {

    @Override

    public void eat() {

        System.out.println("猫吃老鼠");

    }

    public void sleep () {

        System.out.println("猫看电视!!!");

    }

}

public class Demo1 {

    public static void main(String[] args) {

        Dog dog1 = new Dog();

        Person p1 = new Person();

        p1.feed(dog1);//

        p1.feed(new Cat());//传参数传的是个cat

    }

}

十二、多态的应用场景

1、方法参数列表是父类类型,调用方法传参数时,传入子类对象,运行时出现各自子类效果

2、方法返回值是父类类型

3、数组类型是父类类型,数组的真实的值是子类对象

十三、toString 方法

转变为字符串方法,idea插件中的tpg再导入javabean时会自动填上

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;

    }

    @Override// 重写的方法   生成即可

    public String toString() {

        return "{" +

                "名字='" + name + '\'' +

                ", 年龄=" + age +

                '}';

    }

}

public class Demo1 {

    public static void main(String[] args) {

        Person p1 = new Person("张三", 23);

        System.out.println(p1);//com.qf.h_toString.Person@1b6d3586

        //内存地址对程序员是不友好的, 看不懂数据

        //重写toString以后,咱们的对象变得容易让人阅读

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值