第三周周总结

1.局部变量和成员变量的区别?

1)类中的书写位置不同
局部变量:在方法定义中或者方法声明上
成员变量:在类中,方法外~
2)内存位置不同
局部变量:在栈内存中
成员变量:在堆内存中
3)生命周期不同
局部变量:随着方法调用而存在,随着方法调用结束而消失
成员变量:随着对象的创建而存在,随着对象创建完毕,并且使用完毕,等待垃圾回收器回收而消失
4)初始化不同
局部变量:必须在使用之前,必须初始化,否则 提示"可能尚未初始化变量"
成员变量:可以不初始化,系统默认进行初始化,也可以显示初始化

2.this关键字的含义

this:代表当前类对象的地址值引用!
出现的原因:
属性私有化,外界类不能直接去访问成员变量,通过公共的成员方法setXXX(xx),进行赋值访问,存在成员变量和局部变量名称一致的情况,为了区分成员变量和局部变量 ;
this.成员变量名 = 局部变量名;

3.什么是构造方法?构造方法的目的是什么

什么是构造方法:
构造方法:
1)方法名和类名相同
2)没有返回值类型
3)连void没有
构造方法是可以重载的!
构造方法目的:
就是初始化成员变量;

class Student{
         private String name;
         private int age ;
        public Student(){}
        public Student(String name,int age){
            this.name = name ;
            this.age = age ;
        }
    }

4.给成员变量赋值的方式有几种

​ setXXX方法赋值
构造方法赋值:有参构造方法

5.Student s = new Student() ;做了哪些事情?(内存中)

​ 1)加载学生类,----Student.class
2)在栈内存为s变量开辟栈内存空间
3)new Student()---->在堆内存中申请空间
4)通过无参构造方法为成员变量进行默认初始化
5)申请的堆内存空间里面的成员变量默认初始化完毕,产生堆内存 “空间地址值”
6)将堆内存中"空间地址值" 赋值给栈内存的变量s
7)栈内存的变量s指向堆内存空间地址值!

6.一个标准类的写法格式(重点)

class Student{
    //成员变量私有化
    private String name ;
    private int age;
    //无参构造方法
    public Student(){}
    //有参构造方法
    public Student(String name,int age){
        this.name = name ;
        this.age =age;
    }
    //公共的成员访问方法
    public void setName(String name){
        this.name = name ;
    }
    public String getName(){
        return name ;
    }
    public void setAge(int age){
        this.age =age;
    }
    public int getAge(){
        return age ;
    }

}

形式参数是引用类型(重点)

package 形参是引用数据类型;
class Dog{
    public  void  eat(String toeat){//有参函数
        System.out.println("狗子正在吃"+toeat);
    }
}
class DogDemo {
    public void Run(Dog dog){//方法的形式参数是一个引用类型:Dog类    ,实际调用,需要去创建Dog类的对象!i//
           dog.eat("牛排");
           /*引用的是eat方法;由于引用的方法有参所以这里也得有参*/
    }
}
public class ArgsDemo2 {
    public static void main(String[] args) {
        Dog d=new Dog();
        DogDemo dd=new DogDemo();
        Dog i=new Dog();//分别创建对象
         d.eat("骨头");//引用eat方法
         dd.Run(i);//引用的是Run方法
    }
}

匿名对象

·

格式:
- 没有名字的对象:格式
- new 类名() ;
- 匿名对象的特点:
- 1)直接在堆内存中开辟空间,使用完毕,被垃圾回收器回收(用完就回收了)
- 2)匿名对象在实际开发中使用居多; 匿名对象不要使用多次,使用一次即可!
- 3)匿名对象可以作为参数传递


- 有名字的对象:格式
- 类名 对象名 = new 类名() ;

·

·

package 匿名对象;
class Car{//车类
    public void drive(String className){
        System.out.println("汽车正在"+className);
    }
}
class CarDemo{
    public void method(Car c) {
        c.drive("冲向悬崖");
    }
}
public class NoName {
    public static void main(String[] args) {
        //普通版本==
//       StudentDemo sd=new StudentDemo();
        Car  c=new Car();
//       sd.method(c);
//        System.out.println("----------");
//        sd.method(new Car());
//        System.out.println("----------");
        //匿名对象版本==格式:匿名对象就是=>new 类名();
        new CarDemo().method(c);//没有前面的
        /*其实就是前面的sd.method(c)这个访问方法写成
        *   new CartDemo().method(c);   其中的sd==new CarDemo
        * 创建对象的时候去掉前面的CarDemo sd= */
    }

}

:注释掉的地方是其他办法 这里只保留了匿名方法



# **static**

每一个对象都需要在堆内存中开辟空间,在堆中需要进行默认初始化和显示初始化,同一个"属性"都需进行初始化操作,比较麻烦!

### **Java提供了一个关键字 "static"---本身的概念 "共享,共用的意思"**

package StaticDemo;

class Person{
    //static 愿意共享的意思 定义一个person类
    private String name;
    private  int age;
    private static   String country;
    //加了static 就是说可以共享这个定义的量

    public Person(String name,int age){
        this .name=name;
        this.age=age;
        //不用写country 因为被static共享了
    }
    public Person(String name,int age,String country){
        this.name = name ;
        this.age = age ;
        this.country = country ;
    }//再写一个带country是因为至少得有一个带 用来接收下面的第一个带国家的实参
    public void show(){
        System.out.println("姓名"+name+"年龄"+age+"国家"+country);
    }
}
class Test {
    public static void main(String[] args) {
        Person p=new Person("杰克",25,"USA");
        p.show();
        Person p2=new Person("麦克",21);
        p2.show();
        Person p3=new Person("鲁斯",18);
        p3.show();
        Person p4=new Person("张三",23);
        p4.show();
    }
}

静态static 特点(重点)

Ctrl+N全局搜索

·

1)被static修饰的成员(变量/方法)随着类的加载而加载,优先于对象存在! (对象创建: 类名 对象名 = new 类名() 😉

·

- 某个类要先被编译产生–>类名.class—>类在运行的时候,加载过程要将静态的成员都先进入方法区的静态区中!
- 2)static和this不能共存!
- this:代表是当前类对象的地址值引用—说明对象创建完毕,才能使用this.变量名 -->访问成员变量 (对象成员)
- static:随着类的加载而加载,被static修饰的成员—>“类成员”
- 3)如果有一个变量体现出被共享,被共用—>此时用"static"修饰
*
- 举例:
- 水杯中的水 (不行)
- 饮水机的水(可以被共享)
- 4)访问方式:(必须记住)
- 类成员—>被static修饰的,特有访问 方式
- 类名.变量名; //在访问本类中静态变量
=>Demo.num2
- 类名.方法名() ;//在访问本类中的静态方法=>Demo.method
*
```

·

注意事项

- 我们所说的成员变量/成员方法---->默认都是 非静态的!
 1)非静态的成员方法里面,皆可以访问静态的变量/方法,也可以访问非静态的变量/方法!
 2)静态的方法只能访问静态的成员,不能访问非静态的
-记住: 静态只能访问静态!

代码块(重点)

概念

Java中的代码块是一个{}包裹起来的内容!

分类

·

局部代码块—>方法定义中 作用:限定局部变量的生命周期

- 构造代码块—>类的成员位置定义的{}
- 作用:在执行构造方法之前,如果存在构造代码块,先执行构造代码块,
- 然后在执行构造方法 ,就是给数据进行初始化的!
- 静态代码块—>类的成员位置定义的
。。。。。。。。。。。。。。。。。。。。。。。
- static{
- }
- 特点:跟类相关,类一加载,先执行,而且只执行一次(因为类就加载一次)
- 优先级最大

·

优先级

·

静态代码块 > 构造代码块 > 构造方法!

·

\## 普通代码块顺序例子

\```java
class Student2{
    static{
        System.out.println("Student的静态代码块1") ;
    }

    public Student2(){
        System.out.println("Student的无参构造方法") ;
    }

    {
        System.out.println("Student的构造代码块1") ;
    }

    {
        System.out.println("Student的构造代码块2") ;
    }

    public Student2(String str){
        System.out.println("Student的有参构造方法") ;
    }

    static{
        System.out.println("Student的静态代码块2") ;
    }
}
class StudentTest{
    static{
        System.out.println("高圆圆已经42了,我很伤心") ;
    }
    public static void main(String[] args){
        Student2 s = new Student2() ;
        Student2 s2 = new Student2("hello") ;
    }
}

走法:先走所有的static代码块=>static{System.out.println("高圆圆已经42了,我很伤心");}”
“static{System.out.println("Student的静态代码块1");}”
“ static{System.out.println("Student的静态代码块2");}”
再走有/无参构造代码块=>{System.out.println("Student的构造代码块1");}”
“ {System.out.println("Student的构造代码块2") ;}”
再走有/无参构造方法的普通代码块=>{System.out.println("Student的无参构造方法");}”
“{System.out.println("Student的构造代码块1");}”
“{System.out.println("Student的构造代码块2");}”
此时   Student2 s = new Student2() ;已经运行结束了  接下来执行    Student2 s2 = new Student2("hello") ;这个类对象也就是上面的有参构造函数
//解释一下  这里为啥要再走一遍构造代码块1和2,因为static走一遍就消失了,但是构造代码块又不消失,static
//消失,走方法,无参的构造方法执行了一遍了,不再执行了,构造代码块和构造代码块2就会再次运行然后走下面的
//有参构造方法
最后走有参构造方法=>{System.out.println("Student的有参构造方法");}”运行结束

子类父类叠加代码块顺序例子!

/**
 * 看程序,写结果
 * 考点:
 *      代码块的优先级
 *      静态代码块 > 构造代码块 > 构造方法
 *      继承关系问题
 *          子类的所有构造方法默认父类的无参构造方法,目的就是让父类初始化的,然后在子类初始化!
 */
class Person{
    public Person(){
        System.out.println("这是Person类的无参构造方法");
    }
    static{
        System.out.println("Person的静态代码块");
    }
    {
        System.out.println("Person的构造代码块");
    }
}
//子类
class Student extends  Person{
    public Student(){
        //super();
        System.out.println("Student的无参构造方法");
    }
    public Student(String name){
        System.out.println("Student的有参构造方法"+name);
    }
    {
        System.out.println("Student的构造代码块");
    }
    static{
        System.out.println("Student的静态代码块");
    }
}
public class ExtendsTest2 {
    public static void main(String[] args) {
        Student s = new Student() ;
        Student s2 = new Student("高圆圆") ;
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nmv3cAkd-1678542654470)(file:///C:\Users\29903\AppData\Local\Temp\ksohtml16652\wps1.jpg)]

子类父类叠加代码块顺序例子!

class Root {
    static {
        System.out.println("Root的静态初始化块");
    }
    {
        System.out.println("Root的普通初始化块");
    }
    public Root() {
        System.out.println("Root的无参数的构造器");
    }
}
class Mid extends Root {
    static {
        System.out.println("Mid的静态初始化块");
    }
    {
        System.out.println("Mid的普通初始化块");
    }
    public Mid() {
        System.out.println("Mid的无参数的构造器");
    }
    public Mid(String msg) {
        this();
        System.out.println("Mid的带参数构造器,其参数值:" + msg);
    }
}
class Leaf extends Mid {
    static {
        System.out.println("Leaf的静态初始化块");
    }
    {
        System.out.println("Leaf的普通初始化块");
    }
    public Leaf() {

        System.out.println("Leaf的构造器");
    }
}
class LeafTest {
    public static void main(String[] args) {
        new Leaf();
    }
}
结果:
Root的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
Root的普通初始化块
Root的无参数的构造器
Mid的普通初始化块
Mid的无参数的构造器
Leaf的普通初始化块
Leaf的构造器

继承

Object是所有的子类的父类 最高权限

定义:将多个类的共性内容抽取到一个独立的类种,让这个类和多个类产生一种关系:继承

目的好处:
1 提高代码的复用性

2 增强代码后期维护

3 类与类的关系 继承关系 是多态的前提条件!

4 不能为了部分功能就用继承

5 使用的前提是:如果一个类A是类B的一种,或者类B是类A的一种!

核心思想体现一种“is a”的关系

特点

类是java中最基本的单元
1.JAVA语言中,类与类的关系 只支持单继承,不支持多继承
反例:
class Fu{}

​ classFu2{}

​ class Zilei extends Fu,FU2{}
2.类和类之间虽然不支持多继承 但是支持多层继承
例子:
class GrandFather{
publiv void methond1)(){
System.out.println(“我是爷爷”);}
}
clas Father extends GrandFather{
publiv void methond1)(){
System.out.println(“我是爸爸”);}
}
class son extends Father{
publiv void methond1)(){
System.out.println(“我是儿子”);}
}

注意事项

继承的注意事项:
1)子类继承父类,是可以继承父类所有的东西,只不过父类的私有的属性以及方法只能在本类中访问;子类是不能直接访问到的,但是可以间接的通过公共方法来访问!
2)子类继承父类,不能继承父类的构造方法(无参/有参构造),可以通过 "super"来访问父类的构造方法!

普通继承的例子

写错位置了…

package ExtendsDemo;

class person{
    public void Eat(){
        System.out.println("人饿了要吃饭");
    }
    public  void Sleep(){
        System.out.println("人困了要睡觉");
    }
}
class Man extends person{}
class Woman extends  person{}

public class Demo1 {
    public static void main(String[] args) {
        Man m = new Man();
        Woman w = new Woman();
        m.Sleep();
        m.Eat();
        w.Eat();
        w.Sleep();
    }
}

实际开发原则必须遵守“低耦合,高内聚”

耦合: 类和类的关系越少越好 耦合性只能降低 不能避免

内聚: 解决某件事情或者功能的执行力 一个类能完成尽量一个类完成

子类继承父类,子类如何访问父类的构造方法?

通过super关键字


*** 1)子类继承父类,不能继承父类的构造方法,但是可以通过super访问,子类的所有构造方法默认访问父类的无参构造方法!
** 子类的构造方法的第一句话:都有super() ; 访问父类的无参构造方法*
*** 原因:
** 子类继承父类,可能用到父类的属性(成员变量)这些数据,必须让父类先初始化,然后子类才能初始化(构造方法,就是给数据初始化的)*
*** 这种过程----继承中 “分层初始化”
** 2)永远建议把父类的无参构造方法给出来,可能导致子类的构造方法报错*

静态代码块 > 构造代码块 > 构造方法
** 继承关系问题*
*** 子类的所有构造方法默认父类的无参构造方法,目的就是让父类初始化的,然后在子类初始化!

子类继承父类,如果子类的成员变量名称和父类的成员变量名称一致,如何访问呢?

一个类的成员:
成员变量
成员方法
构造方法
子类继承父类,子类中 成员变量如果父类中的成员变量名称不一致的情况:比较简单,分别访问即可!
子类继承父类,如果子类的成员变量名称和父类的成员变量名称一致,如何访问呢?
a)先在子类的局部位置(子类的成员方法中定义变量:局部变量)找,如果存在,就使用
b)如果子类的局部位置没有,然后才在子类的成员位置找,如果存在,就使用
c)如果子类的成员位置没有,然后在父类的成员位置找,如果存在,就使用
d)如果父类的成员位置也没有,说明当前没有这个变量,就访问报错!
一句话:就近原则!

this和super在当子类变量名和父类一样时的用法

System.out.println(num);//访问局部变量
System.out.println(this.num);//访问当前类的成员变量
System.out.println(super.num);//访问父类的成员变量

需要在控制台分别打印30,20,10


        class Test{
                public static void main(String[] args){

                    Zi zi = new Zi();
                    zi.show() ; 
                }
        }

        class Fu{
                int num = 10;
        }
        class Zi extends Fu{
                int num = 20 ;
                public void show(){
                    int num = 30 ;
System.out.println(num);//访问局部变量
System.out.println(this.num);//访问当前类的成员变量
System.out.println(super.num);//访问父类的成员变量
                }
        }

方法重写

/*
*** 继承关系中,成员方法的访问
*
***** 子类继承父类,如果子类和父类的方法名不一致,分别调用即可! (简单)


***** 如果子类出现了和父类一模一样的方法,如何访问呢?
*** 子类会将父类的功能进行覆盖(复写/重写)—>override:方法重写**

多态

什么是多态?
从宏观角度去说:一个事物(能看到真实存在的)体现出的不同形态!
举例:
水—>固态 气态 液态
从内存角度去说:一个对象它的所在的类型的变化
举例:
Cat c = new Cat() ;
Animal a = new Cat() ; //堆内存是猫 从右边—>左边:猫是动物


*** 前提条件:
** 1)必须存在继承关系,才能使用多态*
*** 2)必须存在方法重写,子类继承父类,部分功能将父类进行重写,比如:动物都要吃和睡,具体的动物类:猫/狗/猪,吃和睡的动作不一样
** 3)必须存在父类引用指向子类对象 ----->多态的 “向上转型”*
*** class 父类名{}
** class 子类名 extends 父类名{}*
*** //多态测试—
** 父类名 对象名 = new 子类名() ;*
*** 父类名 对象名 = new 子类名() ;
** 多态的成员访问特点:*
*** 成员变量:编译看左,运行看左!


*** 成员方法(默认都是非静态): 如果子类重写了父类的方法,编译看左,运行看右!
** 静态方法算不上重写,和静态的都是类成员! (访问方式都是类名来调用的)*


** 构造方法:继承是多态的前提条件,所以在使用父类引用指向子类对象:Fu fu = new Zi() ;*
*** 还是要遵循"分层初始化",先让父类构造初始化,然后在是子类构造初始化!


***/

多态的好处

* 多态的好处:

  •  1)可以提供代码的复用性(由继承保证的)
    
  •  2)可以提高代码的扩展性(健壮性)--->由多态保证
    
  •                          父类引用指向子类对象
    

多态弊端

多态的弊端:
** 不能访问子类的特有功能 父类名 对象名 = new 子类名() ; “向上转型”*


** 如何解决呢?*
*** 方案1:
** 直接创建具体的子类对象 子类名 对象名 = new 子类名() ;*
*** 虽然可以这种方式可以,但是从内存角度考虑:消耗资源,浪费空间,又需要去开辟堆内存!
** 方案2:*
*** 多态本身:父类引用指向子类对象,能不能将父类的引用转换成子类型?
** “向下转型”---->强转类型转换的格式 ,前提必须有"向上转型"*
*** 数据类型 变量名 = (目标数据类型)(初始化值或者表达式) ;

package Test;
//父类
public class Work {
    private  String name;
    private  String emid;
    private  int salary;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmid() {
        return emid;
    }

    public void setEmid(String emid) {
        this.emid = emid;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }


    public Work(){}
    public Work(String name, String emid, int salary) {
        this.name = name;
        this.emid = emid;
        this.salary = salary;
    }
public void work(){
    System.out.println("人都需要工作");
}
}


package Test;
//子类1
public class programer extends Work {

    public programer(String name, String emid, int salary) {
        super(name, emid, salary);
    }
    public programer() {
    }
    //重写父类方法 初始化父类
    public  void work(){
        System.out.println("程序员每天敲代码");
    }
    //子类特有的功能
    public void study(){
        System.out.println("程序员爱喝咖啡");//特有功能
    }
}


package Test;
//子类2
public class Mannger  extends Work{
    private int bouns;
    public int getBouns() {
        return bouns;
    }
    public Mannger(){}
    public Mannger(String name, String emid, int salary, int bouns) {
        super(name, emid, salary);
        this.bouns = bouns;
    }
    public void setBouns(int bouns) {
        this.bouns = bouns;
    }    public Mannger(int bouns) {
        this.bouns = bouns;
    }
    public void work(){//重写父类方法 初始化父类
        System.out.println("经理平时就香车美女谈生意");
    }
    public void tread(){
        System.out.println("经理全国各地跑业务");//特有功能
    }
}




package Test;
//测试类
public class WorkMan {
    public static void main(String[] args) {
        Work w = new programer();
        w.setEmid("333");
        w.setName("王二小");
        w.setSalary(15000);
        System.out.println("注意看这个男人叫" + w.getName() + "工号" + w.getEmid() + "薪水" + w.getSalary());
        programer pro = (programer) w;//强转的时候先写 programer pro=w;再分号后面ait +回车
        pro.study();
        Work w2 = new Mannger();
        w2.setName("李成功");
        w2.setEmid("x001");
        w2.setSalary(20000);
        System.out.println("注意看这个男人叫" + w2.getName() + "工号" + w2.getEmid() + "薪水" + w2.getSalary() + "奖金是" + ((Mannger) w2).getBouns());
        Mannger man = (Mannger) w2;
        ((Mannger) w2).tread();
        ((Mannger) w2).setBouns(2000);

    }
}

1.静态代码块,构造代码块,构造方法的优先级

优先级
静态代码块 > 构造代码块 > 构造方法

2.static关键字的特点

​ 1.被static修饰的变量/方法,随着类的加载而加载,优先于对象存在
2.staitc关键字不能和this共存
3.具有"共享,共用"的意思
4.特有访问方法,使用类名访问 (类成员)
类名.变量名;
类名.方法名();

3.什么是继承?继承的好处

继承:
将多个类的共性内容抽取到一个独立的类中,让这个独立的类和这多个类产生一种关系,“extends”
好处:
1)可以提高代码的复用性
2)可以增强代码的维护性
3)类与类的关系,是多态前提条件!
所有开发原则必须遵循"低耦合,高内聚"

4.继承的特点

特点:
1)类与类之间,在Java语言中,只支持单继承,不支持多继承
2)不支持多继承.可以多层继承

5.继承中,子类和父类出现的成员变量名称一致的情况,如何访问

继承关系中,成员变量一致:
1)在子类的局部位置先找,如果有就使用;
2)如果子类局部位置没有,会在子类的成员位置中找,有就使用;
3)如果子类的成员位置也没有,会在父类的成员位置找,有就使用
4)如果父类中的成员位置也没有,访问了不存在的变量(编译报错)
class Fu{}
class Zi extends Fu{}
//测试
Zi z = new Zi() ;

6.继承中,子类继承父类,构造方法如何访问?

子类继承父类,构造方法的访问:
构造方法是不能继承的!
构造方法目的为了给类的成员进行初始化;
继承关系中,子类继承父类,默认所有的子类的构造方法通过super() ;访问父类的构造方法
建议:描述一个事物,使用"类"来进行定义,永远 给无参构造方法;
如果没有给出父类的构造方法,但是给了父类的有参构造方法,那么默认子类的所有构造方法都会报错!
解决方案:
1)要么直接手动给出父类无参
2)假设不给给出父类无参构造方法,直接让子类的所有构造方法通过super(xxx);来访问父类的有参
3)子类所有的构造方法中只要有一个能够父类初始化!

class Fu{
//公共的属性
public Fu(){}
}
class Zi extends Fu{
public Zi(xx xx){
//子类的有参构造方法
}
}

final

·

定义一个父类,子类重写父类的某个成员方法,通过方法重写,最终子类将父类将父类方法覆盖

- 但是有的时候,父类不让子类将自己的某个成员方法进行重写(为了父类的方法的安全性!),Java提供了关键字—>final


- final:是一个状态修饰符 (最终的,无法更改的)

·

·


面试题

方法重写和方法重载的区别

override和overload的区别

方法重载:
在定义方法的时候,为了提高功能的扩展性,同一个方法名,可以使用不同的参数进行传递!
方法名相同,参数列表不同,与返回值无关!
参数列表不同:
1)参数个数
2)参数类型
3)类型的先后顺序
方法重写:
是在继承关系中使用的;
子类继承父类,子类的功能想沿用父类的功能,同时使用自己的功能,子类出现了和父类一模一样的方法,–方法重写(覆盖/复写)

子类继承父类,如果要重写父类的功能,访问权限不能够更低,最起码跟父类的成员方法一致,要么永远public!
举例:
人:
eat() 吃的功能
员工:
work() 都需要工作
程序员也是员工 ---->日日夜夜敲带
项目奖经理也是员工---->吃饭喝酒谈项目

this和super的区别

概念区别
this:代表是当前类对象的地址值引用
super:代表父类的对象的地址值引用(父类的空间标识)
成员访问的区别:
this.变量名; 访问本类的成员变量
super.变量名; 访问父类的成员变量
this.方法名() ; 访问本类成员方法
super.方法名() ;访问的父类的成员方法
this() ; 访问本类的无参构造方法
this(xxx); 访问的本类的有参构造方法
super() ;访问的是父类的无参构造方法
super(xxx) ; 访问的是父类的有参构造方法

final修饰基本数据类型和修饰引用数据类型 的区别?

​ final修饰的引用数据类型,当前不能在开辟堆内存(不能重新new),里面的成员变量依然可以进行赋值
final修饰的基本数据类型,基本数据数据值不能在改变!

final的特点,finalize,finally的区别?

final是一个状态修饰符.最终的,无法更改的!
修饰类,该类不能被继承
修饰成员方法,该方法不能被重写
修饰变量,此时变量是一个常量;不能在重写赋值
finalize:是一个方法名,是后面jvm当前确定堆内存中对象没有更多引用的时候,来通过垃圾器来调用进行回
收的方法!
finally:是关键字,是后面Java中去处理"异常"的一种格式:捕获异常
标准格式
try{
//可能出现问题代码
}catch(异常类名 变量名){
处理异常
}finally{
//释放相关的系统资源 (后面学习IO流,读取文件/写文件等等)
}

*** 什么时候将一个变量定义为成员变量?**

变量—>成员变量/局部变量
将一个变量定义为成员变量的时机:
** 如果这个变量能够描述现实世界事物的属性—>定义为成员变量,否则都是"局部变量*

抽象abstract

什么是抽象?

  • 举例:
  •      将猫和狗的共性内容,抽取到了动物(本身就是统称,概括性的)了中,比如:吃和睡的功能,但是在动物了中
    
  • 将吃和睡给出了具体体现,只有看到具体的事物才能知道它具体吃和睡的行为!所以在父类将这些行为,只是给出一个方法声明即可!
  • 仅仅给出方法的声明---->含义没有方法体{},抽象功能---->
  •  有抽象的方法的必须为抽象类
    
  •  抽象类中不一定都是抽象方法!(部分的功能,抽象功能,必须让子类必须重写!)
    
  • 抽象方法(成员方法)的格式:
  •  权限修饰符 abstract 返回值类型 方法名(空参/带参) ;
    
  • 抽象类的本质:
  •  强制子类必须将父类的所有的抽象方法,必须实现(重写)
    

*抽象类的特点:

  •  1)不能实例化(不能new 创建对象)
    
  •  2)抽象类的子类一定有具体类,否则无法进行实例化的!
    

抽象abstract关键字不能和哪些关键字共存?
abstract不能和private共用:
被private修饰的只能在当前类访问,而abstract修饰的方法,它需要强制子类进行重写;
abstract不能和static共用:
abstract修饰的成员方法,需要被子类重写,还是抽象类多态进行实例化Fu fu = new Zi() ;
而static随着类的加载而加载(静态方法算不上重写),跟类相关的!
abstract不能和final共用:
被final修饰的成员方法不能被重写,而abstract修饰的成员方法,强转子类重写!
abstract:用在类上,标记这个类----抽象类
用在方法上,标记这个方法是一个抽象方法!
结合public使用居多

抽象的特点

抽象类的成员特点:

  • 1)成员变量:
    
  •      可以是变量也可以自定义的常量
    
  • 2)成员方法
    
  •      既可以有抽象方法,也可以有非抽象方法!
    
  • 3)构造方法
    
  •      还存在继承关系,分层初始化--->先父类构造初始化,然后是子类构造初始化!
    
  •      无参构造方法/有参构造方法都可以存在,目的都是为了数据进行初始化!
    

有抽象类方法的类必须是抽象类

抽象类的方法不一定是抽类

接口Interface

体现的是这个事物本身不具备的功能 是一种额外扩展功能

interf {}

接口的子类(子实现类) implements

接口的方法只能是抽象方法

接口不能实例化

如何实例化

接口多态

接口名 对象名 =new 接口的子实现类
接口中所有变量都是常量 接口类隐藏了public fianl static

类与类 类与接口 接口和接口的关系

在Java中,

  •  类与类:
    
  •          继承关系,extends,而且只支持单继承,不支持多继承,但是可以多层继承!
    
  •  类与接口
    
  •          实现关系,implements,而且一个类继承另一个类的同时,是可以实现多个接口的!接口名和接口名直接逗号隔开
    
  •              class LoverImpl extends Lover implements  Love,Study{
    
  •  接口与接口
    
  •          继承关系,extends,不仅支持单继承,也支持多继承,也可以多层继承!
    

接口中的成员特点:

·

接口中的成员特点:

- 成员变量:只能是常量 存在默认修饰符 public static final
- 成员方法:(非静态):只能是抽象方法,存在默认修饰符 public abstract
- 在接口中是可以定义静态方法,必须有方法体(特例)
- 构造方法: 没有构造方法! 因为子实现类和接口的关系是implements实现关系,
- 只是将接口暴露的额外功能进行实现!

·

接口体现的是这个事物本身不具备的功能,是一种额外的扩展功能!

  • 只要这个事物实现了接口,它就具备这个功能!
  • 如何定义接口
  •  java定义接口
    
  •  interface  接口名{}
    
  •  接口的子类(子实现类) implements  接口名{
    
  •      强制子实现类必须将接口中所有抽象方法必须重写!(实现)
    
  •  }
    
  • 接口的特点:
  •       1)接口不能实例化(不能创建对象)
    
  •       2)接口如何实例化?
    
  •              接口多态
    
  •              接口名 对象名  = new 接口的子实现类名() ;  (前提:子实现类是非抽象的,就是一个具体类)
    

*开发中:

  • 接口名和子实现类的命名规范(开发项目中)
  •  举例:
    
  •      接口名:  interface Inter{}
    
  •      接口的子实现类命名: 接口名 +Impl
    
  •              class InterImpl implements Inter{}
    

接口和抽象 的区别

区别:

1)成员的区别

​ 抽象类:

​ 成员变量:既可以常量(定义final修饰的),也可以是变量

​ 成员方法:既可以存在抽象方法,而且也可以存在非抽象方法

​ 如果定义抽象方法,abstract不能省略!

​ 构造方法:存在,无参构造/有参构造方法,让类的数据进行初始化(构造初始化)

​ 接口:

​ 成员变量:只能是常量,存在隐藏的默认修饰符:public static final’

​ 成员方法:只能是抽象方法

​ 构造方法:没有

2)关系区别:

		类与类:继承关系,只支持单继承,不支持多继承

		类接口:实现关系,一个类继承另一个类的同时,可以实现多个接口

		接口与接口:继承关系,可以单继承,也可以多继承以及多层继承

3)设计理念的区别

	抽象类:有继承关系,抽象类不能创建对象,借助于抽象类多态(子类是具体类),进行实例化;

	体现的核心思想: "is a"的关系

				A类是B类的一种或者B类是A列的一种

				水果:

					橘子

					香蕉

    接口:体现的是事物的一种额外的扩展功能,本身不具备,需要实现接口才能具备这个功能!

​ 体现的核心思想:

​ "like a"的关系

​ 猫"跳高" -->

​ 狗"做计算"—> 跳高以及做计算都是额外功能;

形参是具体类抽象类接口类

具体类:调用该方法,此时实际参数需要的是当前类的对象!

package com.qf.args_01;

/**

  • 方法的形式参数问题: 只研究引用类型
  •          方法形式参数:
    
  •                  具体类:调用该方法,此时实际参数需要的是当前类的对象!
    

*/
class Student{
public void studyJavaEE(){
System.out.println(“正在学习JavaEE之JavaSE”) ;
}
}
//定义一个StudentDemo类
class StudentDemo{

​ public void show(Student s){//方法的形式参数是一个学生类型
s.studyJavaEE() ;
}
}

//测试类
public class ArgsDemo1 {
public static void main(String[] args) {
//访问StudentDemo类中的show方法
StudentDemo sd = new StudentDemo() ;
Student student = new Student() ;
sd.show(student) ;
System.out.println(“----------------------”) ;
//另一种方式:匿名对象
new StudentDemo().show(new Student());

​ }
}

抽象类:调用该方法,此时实际参数需要的是当前抽象类的子类对象!

package com.qf.args_01;

/**

  • 方法的形式参数问题: 只研究引用类型
  •          方法形式参数:
    
  •              抽象类:调用该方法,此时实际参数需要的是当前抽象类的子类对象!
    

*/
//定义一个Person类
abstract class Person{
/public void work(){
System.out.println(“人都需要工作”);
}
/

​ public abstract void work() ;
}
//定义一个PersonDemo类
class PersonDemo{
public void function(Person p){//方法的形式参数是引用类型–抽象类,抽象类不能new,需要传递抽象类的子类对象!
p.work() ;
}
}

//定义抽象类的子类(具体类)
class Worker extends Person{

​ @Override
public void work() {
System.out.println(“爱工作,爱Java,爱高圆圆!”);
}
}
//测试类
public class ArgsDemo2 {
public static void main(String[] args) {
//访问PersonDemo类中的function方法?
PersonDemo pd = new PersonDemo() ;
//Person p = new Person() ;抽象类不能实例化(不能创建对象)
Person p = new Worker() ;
pd.function§ ;
System.out.println(“-----------------------”) ;
new PersonDemo().function(new Worker());
}
}

接口类型:调用该方法,此时实际参数需要的是接口的子实现类对象!

package com.qf.args_01;

/**

  • 方法的形式参数问题: 只研究引用类型
  •          方法形式参数:
    
  •                  接口类型:调用该方法,此时实际参数需要的是接口的子实现类对象!
    
  •            开发中:方法形式参数是具体类以及接口情况居多的!
    

*/
//定义一个接口
interface Love{
public abstract void love() ;
}
//定义一个类:LoveDemo
class LoveDemo{
public void method(Love l) {//方法的形式参数是一个接口? 接口不能new,需要接口的子实现类对象
l.love();
}
}
//需要有定义接口的子实现类,实现Love接口
class LoveImpl implements Love{

​ @Override
public void love() {
System.out.println(“love Java!”);
}
}

//测试类
public class ArgsDemo3 {
public static void main(String[] args) {
//要访问LoveDemo类中的method方法?
LoveDemo ld = new LoveDemo() ;
// Love l = new Love() ;//接口不能实例化
// ld.method(l);

​ //接口多态:接口名指向子实现类
Love l = new LoveImpl() ;
ld.method(l);
System.out.println(“-----------------------”);
new LoveDemo().method(new LoveImpl()) ;
}
}

开发中:方法形式参数是具体类以及接口情况居多的!

返回值是具体类抽象类接口类

具体类:需要返回该具体类的对象!

package com.qf.return_02;
/**

  • 方法的返回值问题:
  •  要么基本类型/引用数据类型
    
  •  基本类型:简单,要什么类型,使用指定的类型接收即可!
    
  •  研究的方法的返回值引用类型:
    
  •          方法的返回值如果是引用类型:
    
  •                      具体类:需要返回该具体类的对象!
    
  •                      抽象类:
    
  •                      接口:
    

*/
class Demo{
//对两个数据求和
public int sum(int a,int b){
return a+ b;
}
}
//定义学生类
class Student{
public void study(){
System.out.println(“好好学习,天天向上!”);
}
}
//StudentDemo类
class StudentDemo{
public Student show(){
//return Student ; 错误
//方式1:
// Student s = new Student() ;
//return s ;

​ //方式2:匿名对象
return new Student() ;

​ }
}
//测试类
public class ReturnDemo1 {
public static void main(String[] args) {
Demo d = new Demo() ;
int result = d.sum(10, 15);
System.out.println(result);
System.out.println(“--------------------”);

​ //访问StudentDemo类中的方法
StudentDemo sd = new StudentDemo() ;
Student student = sd.show(); //show方法就是new Student()
student.study();
}
}

抽象类:需要返回该抽象类的子类对象!

package com.qf.return_02;

/**

  •  研究的方法的返回值引用类型:
    
  •          方法的返回值如果是引用类型:
    
  •                      具体类:需要返回该具体类的对象!
    
  •                      抽象类:需要返回该抽象类的子类对象!
    
  •                      接口:
    

*/
//定义一个Person类
abstract class Person{
public abstract void work() ;
}
//PersonDemo类
class PersonDemo{
public Person function(){//方法的返回值是一个抽象类
//?
// return new Person() ; 抽象类不能实例化
//方式1:抽象类多态
//Person p = new Programmer() ;
//return p;

​ //方式2:直接匿名对象 (创建子类对象)
return new Programmer() ;
}
}

//定义一个类,继承Person
//程序员
class Programmer extends Person{

​ @Override
public void work() {
System.out.println(“程序员日日夜夜敲代码!”);
}
}

//测试类
public class ReturnDemo2 {
public static void main(String[] args) {

​ //访问PersonDemo类的function方法
PersonDemo pd = new PersonDemo() ;
Person person = pd.function(); //funciton方法 本质—>创建了子类对象
person.work();
}
}

接口类型:需要返回接口子实现类对象!

package com.qf.return_02;

import sun.util.resources.ms.CalendarData_ms_MY;

/**

  •  研究的方法的返回值引用类型:
    
  •          方法的返回值如果是引用类型:
    
  •                      具体类:需要返回该具体类的对象!
    
  •                      抽象类:需要返回该抽象类的子类对象!
    
  •                      接口:需要返回接口子实现类对象!
    

*/
//定义一个接口
interface Mary{ //结婚的接口
public abstract void mary() ;
}
//定义一个MaryDemo
class MaryDemo{
public Mary method(){
//?
//return new Mary() ;//接口不能new

​ //方式1:
//Mary mary = new MaryImpl() ;
// return mary ;

​ //方式2:
return new MaryImpl() ;
}
}

//需要定义接口的子实现类
class MaryImpl implements Mary{

​ @Override
public void mary() {
System.out.println(“要结婚了,很开心…”);
}
}
//测试类
public class ReturnDemo3 {
public static void main(String[] args) {

​ //需求:访问MaryDemo类中的method方法?
MaryDemo md = new MaryDemo() ;
Mary mary = md.method();
mary.mary();
System.out.println(“-----------------------”);
Mary mary2 = new MaryDemo().method();
mary2.mary();
}
}

包的含义和代码分层(了解)

包—package存储本地Java代码的一个目录(文件夹)

net.qf.pojo//pojo是指存储的实体类(描述现实世界事物的)

net.qf.service//存储的业务接口

impl: 以及业务实现:具体业务实现过程的代码

net.qf.dao// dao(数据访问层:Data Access Object:数据访问对象):数据访问接口

net.qf.utils//utils:工具类–>存储的都是通用的工具类的代码 xxx.java文件

net.qf.test//test:存储的测试接口中的功能代码

权限修饰符

private 私有

(默认修饰符)

proteed 受保护的

public 公开的

同一个包下的同一个类同一个包下的子类/同一个包下的无关类不同包下的子类不同包下的无关类
private/私有yes
默认修饰符yesyes
protected/受保护的yesyesyes
public/公开的yesyesyesyes

private私有修饰符权限最小

instanceof 判断对象名是否为后面这个类型的实例

内部类

java中一个类中定义另一个类:类A中定义类B 。B是A的内部类。A是B的外部类

分类

成员内部类

在外部类中外部类方法外定义的类

可以访问外部类的成员(包括私有)

创建外部类对象,访问外部类的成员方法 间接调用了成员内部类的成员方法

测试类中直接调用内部类成员方法:

适用非静态成员内部类

外部类名.内部类名 对象名=new 外部类名().new 内部类名()

成员内部类可以使用static修饰

特点

静态的成员内部类的所有成员方法,无论静态还是非静态。访问外部类的成员必须先为静态

测试类中直接调用内部类成员方法:

适用静态成员内部类

外部类名.内部类名 对象名=new 外部类名.内部类名();

局部内部类

方法定义中定义的类也是可以访问外部类的成员变量(包括私有)

创建局部内部类的对象就可以访问局部类的方法

JDK8以前 局部内部类访问(外部类成员方法中的)局部变量会报错 需要给局部变量加final才行;

面试题

局部内部类的成员访问局部变量的时候 局部变量有何要求

局部变量的生命周期随着方法的调用而存在,随着方法的调用结束而消失

外部类的成员方法调用完毕之后,此时的局部变量释放了,成员方法中创建了局部内部类对象去访问他的成员方法,间接使用。所以显示加入final 修饰局部变量

匿名内部类:针对抽象类或者接口去使用、

new 类名/接口名(){}

重写类或者接口的抽象功能};

  | **同一个包下的同一个类** | **同一个包下的子类/同一个包下的无关类** | **不同包下的子类** | **不同包下的无关类** |

| ------------------ | ------------------------ | --------------------------------------- | ------------------ | -------------------- |
| private/私有 | yes | | | |
| 默认修饰符 | yes | yes | | |
| protected/受保护的 | yes | yes | yes | |
| public/公开的 | yes | yes | yes | yes |

private私有修饰符权限最小

instanceof 判断对象名是否为后面这个类型的实例

内部类

java中一个类中定义另一个类:类A中定义类B 。B是A的内部类。A是B的外部类

分类

成员内部类

在外部类中外部类方法外定义的类

可以访问外部类的成员(包括私有)

创建外部类对象,访问外部类的成员方法 间接调用了成员内部类的成员方法

测试类中直接调用内部类成员方法:

适用非静态成员内部类

外部类名.内部类名 对象名=new 外部类名().new 内部类名()

成员内部类可以使用static修饰

特点

静态的成员内部类的所有成员方法,无论静态还是非静态。访问外部类的成员必须先为静态

测试类中直接调用内部类成员方法:

适用静态成员内部类

外部类名.内部类名 对象名=new 外部类名.内部类名();

局部内部类

方法定义中定义的类也是可以访问外部类的成员变量(包括私有)

创建局部内部类的对象就可以访问局部类的方法

JDK8以前 局部内部类访问(外部类成员方法中的)局部变量会报错 需要给局部变量加final才行;

面试题

局部内部类的成员访问局部变量的时候 局部变量有何要求

局部变量的生命周期随着方法的调用而存在,随着方法的调用结束而消失

外部类的成员方法调用完毕之后,此时的局部变量释放了,成员方法中创建了局部内部类对象去访问他的成员方法,间接使用。所以显示加入final 修饰局部变量

匿名内部类:针对抽象类或者接口去使用、

new 类名/接口名(){}

重写类或者接口的抽象功能};

范围:局部位置中使用本质:继承了该抽象类或者实现了该接口的子实现类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值