java基础之面向对象(二)

static关键字

静态static关键字的特点:

1)随着类的加载而加载

2)优先于对象存在:

它不能和this共存(this:代表当期类对象的地址值引用)

对象还没有new的时候,当前被static修饰的成员就已经内存了

3)被静态修饰

可以被多个对象共享:有共享共用的意思

举例:饮水机中的水(适合) <==> 水杯共享(不适合!)

4)被静态修饰的变量,方法=>静态变量或者静态方法

我们所说的成员变量和成员方法:都指的是非静态

静态的成员的访问方式:类名.变量\类名.方法名()

5)关于static关键字的使用注意事项:

①非静态的方法既可以访问静态变量,也可以访问非静态的变量;既可以调用静态方法,也可以调用非静态方法

②静态的方法:只能访问静态变量;只能调用静态方法

简单记:静态只能访问静态

静态变量和成员变量的区别

所属不同

静态变量属于类,所以也称为为类变量

成员变量属于对象,所以也称为实例变量(对象变量)

内存中位置不同

静态变量存储于方法区的静态区

成员变量存储于堆内存

内存出现时间不同

静态变量随着类的加载而加载,随着类的消失而消失

成员变量随着对象的创建而存在,随着对象的消失而消失

调用不同

静态变量可以通过类名调用,也可以通过对象调用

成员变量只能通过对象名调用

代码块

在Java中,使用{}包裹棋起来的内容,成为代码块!

代码块的分类

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

构造代码块:在类的成员位置(类中,方法外),使用{}包裹起来作用:给 类中的一些成员进行数据初始化

代码块的特点

每次在执行构造方法之前,如果存在构造代码块,先执行构造代码块中的内容

静态代码块

在类的成员位置,直接使用static{},

特点:

随着类的加载而加载,优先于对象存在!

作用:

也可以通过static代码块,对一些操作 (后期I0流创建文件.JDBC (Java链接数据库注册驱动))

静态代码块就加载一次!

优先级:

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

eg.

package HemoWork.day10;

public class Test01 {

    public static void main(String[] args) {
        new Leaf();

    }
}

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() {
        super("hello");
        System.out.println("Leaf的构造器");
    }

}

运行结果:

Root的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
Root的普通初始化块
Root的无参数的构造器
Mid的普通初始化块
Mid的无参数的构造器
Mid的带参数构造器,其参数值:hello
Leaf的普通初始化块
Leaf的构造器

继承

继承的概念:

将多个类的共性内容抽取到独立的类中,然后这多各类和独立的类产生一种关系:继承关系

继承的好处:

1)提高代码的维护性

2)提高代码的复用性

3)让类和类之间产生了关系,是“多态的前提条件”

什么时候使用继承?

1)不要为了实现部分功能而使用继承关系

2)A is a B的时候可以使用继承

继承的特点:

1)继承只支持单继承,有些语言中支持多继承,但是Java中不支持

2)不支持多继承,但支持多层继承

注意事项:

1)子类继承父类:可以继承父类的非私有的成员,私有的成员外界不能访问,只能在本类中访问。但是可以通过公共访问间接方法

2)构造方法是不能被继承的,但是子类可以简介通过super关键字访问父类的构造方法

成员变量的关系问题:

a)子类继承父类,如果子类中的成员变量名称和父类的成员变量名称不一致,分别访问即可!

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

1)首先在子类的局部位置找,是否存在局部变量名称,如果有,就使用

2)如果没有,就在子类的成员位置找,是否存在这个变量,如果存在,就使用

3)如果在子类的成员位置中没有找到,直接在父类的成员位置中找,如果有,就是使用!

4)如果父类的成员位置都没有,就没有这个变量,报错!

遵循一个原则:就近原则!

继承中无参构造方法的访问:
1)子类继承父类,子类的所有的构造方法都会默认的访问父类的无参方法
2)如果父类中没有无参构造方法子类会怎么样?

子类的所有的构造都会报错! (因为子类所有构造方法默认父类的无参构造方法!)

如何解决呢?

方式1:手动给出父类的无参构造方法(推荐)

方式2:在子类的构造方法中的第一句话:通过super (xxx),间接的访问父类的有参构造方法

方式3:只要子类的所有构造方法中一个能够让父类初始化即可!

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

在一个类中,提供n多个接口,这些功能,方法名相同,参数列表不同,与返回值无关(目的:提高某个功能的扩展性)

参数列表不同:①类型不同,②个数不同,③考虑参数类型的顺序

构造方法也可以重载

方法重写:

在继承关系中,子类出现了和父类一模一样方法声明,重写的目的:子类有自己的功能,需要将父亲的该功能覆盖掉

方法重写时需要注意:

当前子类继承父类时,如果存在方法重写,那么子类重写该方法访问权限不能更低

要么跟父类方法保持一致,要么加上public,最好和父类的修饰一样

什么时候使用继承?、

如果A类是B类的一种,或者B类是A类的一种,这个使用extends完成两者继续关系,体现的是一种"is a"的关系。不要为了部分功能而去使用继承!

eg.

public class People {

    private String name;
    private int age;
    private String sex;

    public People() {
    }

    public People(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    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;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public void eat() {    }

}

class PeopleNan extends People {

    public PeopleNan() {
    }

    public PeopleNan(String name, int age, String sex) {
        super(name, age, sex);
    }

    @Override
    public void eat() {
        System.out.println("南方人吃米饭");
    }

    public String work() {
        return "南方人经商";
    }

}

class PeopleBei extends People {

    public PeopleBei() {
    }

    public PeopleBei(String name, int age, String sex) {
        super(name, age, sex);
    }

    @Override
    public void eat() {
        System.out.println("北方人吃面");
    }

    public String work() {
        return "北方人考学";
    }

}

class PeopleTest {

    public static void main(String[] args) {

        People people = new People();
        PeopleBei peopleBei = new PeopleBei();
        PeopleNan peopleNan = new PeopleNan();

        peopleBei.setName("老北");
        peopleBei.setAge(40);
        peopleBei.setSex("男");

        System.out.println("我是" + peopleBei.getName() + ",今年" + peopleBei.getAge() + ",是个" + peopleBei.getSex()+"的");
        peopleBei.eat();
        System.out.println(peopleBei.work());


        peopleNan.setName("南姐");
        peopleNan.setAge(40);
        peopleNan.setSex("女");
        System.out.println("我是" + peopleNan.getName() + ",今年" + peopleNan.getAge() + ",是个" + peopleNan.getSex()+"的");
        peopleNan.eat();
        System.out.println(peopleNan.work());

    }

}

运行结果:

我是老北,今年40,是个男的
北方人吃面
北方人考学
我是南姐,今年40,是个女的
南方人吃米饭
南方人经商

eg2

public class Animal {

    private String name;
    private int age;
    private String color;

    public Animal() {}

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

    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;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public void eat(){}

    public void play(){}

    public void introduce(){
        System.out.println("我是一只"+getName()+",我是"+getColor()+"色的,今年"+getAge()+"岁");
    }

}

class Cat extends Animal{

    public Cat() {}

    public Cat(String name, int age, String color) {
        super(name, age, color);
    }

    public void eat(){
        System.out.println("猫咪吃饭");
    }

    public void play(){
        System.out.println("猫咪舔自己");
    }

    public void introduce(){
        System.out.println("我是一只"+getName()+"猫,我是"+getColor()+"色的,今年"+getAge()+"岁");
    }

}

class Dog extends Animal{

    public Dog() {
    }

    public Dog(String name, int age, String color) {
        super(name, age, color);
    }

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

    public void play(){
        System.out.println("狗狗吃骨头");
    }

    public void introduce(){
        System.out.println("我是一只"+getName()+"狗,我是"+getColor()+"色的,今年"+getAge()+"岁");
    }

}

class AnimalTest{

    public static void main(String[] args) {

        Animal animal = new Animal();
        Cat cat = new Cat("大黄",3,"黄");
        Dog dog = new Dog("大毛",5,"白");

        cat.eat();
        dog.eat();

        cat.play();
        dog.play();

        cat.introduce();
        dog.introduce();

    }

}

运行结果:

猫咪吃饭
狗狗吃饭
猫咪舔自己
狗狗吃骨头
我是一只大黄猫,我是黄色的,今年3岁
我是一只大毛狗,我是白色的,今年5岁
super和this关键字

this代表本类对应的引用。

super代表父类存储空间的标识(可以理解为父类引用)

final关键字
关于final关键字的特点:

1)可以修饰类,该类不能被继承!

2)可以修饰符成员方法,成员方法不能重写! (根据具体的题意要求!)

3)可以修饰的变量,这个变量此时是一个常量! (自定义常量)

面试题:

final , finally, finalize(的区别?

final的关键字描述以及的三个特点

finally:处理异常用到try… catch… finally(后面讲)

finalize() :跟垃圾回收器有关系:回收内存中没有更多引用的对象(后面在讲常用类)

final修饰的变量:

普通变量:

final int a = 10;

实例变量:

final Student student = new Student();

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

final修饰基本数据类型:基本数据类型的对应的数据值不能在被赋值了,只能赋值一次!

final修饰引用类型:引用数据类型对应的地址值不能被改变

final Student s = new Student() ;//修饰实例变量s, s的堆内存地址值永远是固定值!
new Student() ;//重新开辟 空间(报错)
开发中书写常量:

都使用public static final int a = 100 ;

public:访问权限足够大

static:可以被类名直接访问

final:这个变量是一个常虽

多态

多态的概念

一个事物在不同时刻不同形态

多态的前提条件

1)必须存在继承关系extends

2)必须存在方法重写【子类需要覆盖父类的功能】

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

F f = new Z();
多态的访问特点

1)针对成员变量的访问问题

编译看左(看Fu类是否存在变量,存在,编译不会报错!)
运行看左(使用Fu类的东西)

2)针对成员方法的访问问题(非静态)

编译看左(看Fu类是否存在这个方法,存在,编译不会报错!)

运行看右(存在方法重写,所以最终子类的功能将父类的该功能进行覆盖!)

3)如果成员方法是静态方法(静态成员方法算不上方法重写,直接可以类名来访问,跟类相关的方法)

编译看左(看Fu类是否存在这个静态方法,存在,编译不会报错!),

运行看左(静态方法:子类出现了父类一模一样的静态方法,不能算重写,和类相关)

4)针对构造方法的访问问题:

存在继承关系:还需要让父类先初始化,然后再子类进行数据初始化!(分层初始化!)

多态的好处

1)提高了代码的复用性(有继承保证)

2)提高了代码的扩展性(有多态保证)

多态的弊端

不能访问子类的特有功能

如何解决?(如何访问子类独有的功能)

方案一:具体的子类创建具体的子类对象

Zi z = new Zi() ;
z.成员方法名()
本身Fu f = new Zi();//已经在堆内存中开辟空间了
Zi z = new Zi();//在堆内存中又开辟空间,从内存角度考虑,这种比较消耗内存空间

方案二:将父类引用转换为子类引用(向下转型)

Fu fu = new Zi();
Zi zi = (Zi)fu;
需要注意:

向下转型使用不当,就出现java. lang. ClassCastException;类转换异常;属于运行时异常。

当前堆内存中的实例不是该类型时,就会出现问题!

eg

class Animal{

    static String name = "狗";

    int age = 5;

    public Animal() {
    }

    public void eat(){
        System.out.println("饿了就吃");
    }

}

class Dog1 extends Animal{

    String name;

    int age = 2;

    public Dog1() {
    }

    public Dog1(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    public void sleep() {
        System.out.println("狗打呼噜");
    }
}

public class DuoTaiTest {

    public static void main(String[] args) {


        Animal animal = new Dog1("大黄");
        //成员方法
        animal.eat();//子类

        //强制类型转换(向下转型)
        Dog1 dog2 = (Dog1)animal;
        dog2.sleep();

        //成员变量
        int age = animal .age;
        System.out.println(age);//父类

        //构造方法
        //赋值需要向下转型
        System.out.println(((Dog1) animal).getName());

        Animal dog = new Dog1("aa");

        System.out.println(dog.name);

    }

}

运行结果

狗吃骨头
狗打呼噜
5
大黄
狗

eg2

public class JuiceMachineTest {

    public static void main(String[] args) {

        JuiceMachine juiceMachine = new JuiceMachine();
        juiceMachine.makeJuice(new Apple());
        juiceMachine.makeJuice(new Banana());
        juiceMachine.makeJuice(new Orange());

    }

}

class JuiceMachine {
    public void makeJuice(Fruit fruit) {
        fruit.Juice();
    }
}

class Fruit {
    public void Juice() {
        System.out.println("出汁!");
    }
}

class Apple extends Fruit {
    public void Juice() {
        System.out.println("流出苹果汁");
    }
}

class Banana extends Fruit {
    public void Juice() {
        System.out.println("流出香蕉酱");
    }
}

class Orange extends Fruit {
    public void Juice() {
        System.out.println("流出橙汁");
    }
}

运行结果

流出苹果汁
流出香蕉酱
流出橙汁

抽象类

什么是抽象类?

现实世界事物中,某个事物是比较概括性,描述为抽象事物

将某个事务中的一些功能仅仅给出声明即可,没有方法体。

抽象类关键字:abstract关键字

抽象方法的格式:
权限修饰符(eg.pub1ic) abstract 返回值类型方法名 (形式参数列表);
abstract class 类名{}
抽象类的特点:

1)有抽象方法的类一定是抽象类;

2)抽象类中不一定只有抽象方法,还可以有非抽象方法(有方法体) ;

3)抽象类不能实例化=>不能创建对象

通过具体的子类进行实例化(创建对象),抽象类多态Fu fu = new Zi();

4)抽象类的子类有两种情况:

①目前来说:如果抽象类的子类都是抽象类—毫无意义。因为子类也不能new,除非再有具体的子类;

②抽象类的子类是具体类—才能new:抽象 多态的形式Fu fu = new Zi()

抽象类成员的特点:

成员方法
既可以定义为抽象方法,也可以定义为非抽象方法
成员变量:
既可以定义变量,也可以定义常量
构造方法:
既可以有参狗仔,也可以无参构造

abstract关键字和那些关键字冲突:

final:abstract修饰的类继承后,该类的方法需要重写,而final修饰的类不能继承,也不能有子类,方法更不能重写,相互冲突。

private:私有方法子类的方法不能被继承,就不能被重写,而abstract就是要方法重写。相互冲突。

static:static能被实例化可直接调用,abstract是不能被实例化,相互冲突。

面试题:
一个类中没有抽象方法,那么将这个类定义为抽象类的意义何在?

为了不让它直接实例化!

如何实例化?

1)直接具有具体的子类

2)间接具有具体的子类

可能:某个功能的返回值是它本身---->功能里面的逻辑可能就是在new 最具体的子类!

eg

//创建一个名称为 Vehicle类并将它声明为抽象类,在Vehicle类中声明一个NoOfWheels方法,使它返回一个字符串值.
public abstract class Vehicle {
    public abstract String NoOfWheels();
}

//Motorbike类
public class Motorbike extends Vehicle{
    @Override
    public String NoOfWheels() {
        return "双轮车";
    }
}

//Car类
public class Car extends Vehicle {
    @Override
    public String NoOfWheels() {
        return "四轮车";
    }
}

//创建一个带main方法的类,在该类中创建 Car和Motorbike的实例,
public class VehicleTest {

    public static void main(String[] args) {

        Vehicle vehicle1 = new Car();
        System.out.println(vehicle1.NoOfWheels());

        Vehicle vehicle2 = new Motorbike();
        System.out.println(vehicle2.NoOfWheels());

    }

}

运行结果

四轮车
双轮车

eg.2

public abstract class Animal{

    String name;
    int age;
    String sex;

    public Animal() {
    }

    public Animal(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    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;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public abstract void eat();

    public abstract void sleep();

    public abstract void hobit();

    public void introduce(){
        System.out.println("我是"+getName()+",我今年"+getAge()+"岁,我是"+getSex()+"的");
    }
}

//猫类
public class Cat extends Animal {

    public Cat() {
    }

    public Cat(String name, int age, String sex) {
        super(name, age, sex);
    }

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void sleep() {
        System.out.println("猫睡觉");
    }

    @Override
    public void hobit() {
        System.out.println("猫玩毛线");
    }
}

//狗类
public class Dog extends Animal {

    public Dog() {
    }

    public Dog(String name, int age, String sex) {
        super(name, age, sex);
    }

    @Override
    public void eat() {
        System.out.println("狗吃饭");
    }

    @Override
    public void sleep() {
        System.out.println("狗睡觉");
    }

    @Override
    public void hobit() {
        System.out.println("狗打滚");
    }
}


//一个测试类
public class AnimalTest {

    public static void main(String[] args) {

        Animal animal1 = new Dog("大黄",5,"公");
        animal1.introduce();
        animal1.eat();
        animal1.hobit();
        animal1.sleep();

        Animal animal2 = new Cat("nono",4,"母");
        animal2.introduce();
        animal2.eat();
        animal2.hobit();
        animal2.sleep();

    }

}

运行结果

我是大黄,我今年5岁,我是公的
狗吃饭
狗打滚
狗睡觉
我是nono,我今年4岁,我是母的
猫吃鱼
猫玩毛线
猫睡觉

接口

本质是体现一个现实世界事物所具有的额外的扩展抽象

接口的特点:

​ 1)不能实例化(不能创建对象)

​ 如何实例化?通过接口的子实现类(一定是具体类)进行实例化----接口多态(使用时最!)

​ 2)子类实现和接口的关系: implements实现关系

​ 3)接口的子类,要么是抽象类,要么重写接口中的所有抽象方法

接口的成员特点:

​ 成员变量:只能常量,默认用public static final修饰

​ 构造方法:接口没有构造方法

​ 成员方法:只有抽象方法,默认用public abstract修饰

抽象类和接口之间的区别:
1)成员的区别

抽象类:

成员变量:既可以是常量,也可以是变量;

成员方法:既可以是抽象方法,也可以是非抽象方法;

构造方法:既存在有参构造,也存在无参构造;

接口:

成员变量:稚嫩是常量,默认修饰符public static final;

成员方法:只能是抽象方法:默认修饰符 public abstract;

构造方法:接口中没有构造方法

2)关系的区别

类与类之间的关系:extends 继承关系

类与接口之间的关系:implements 实现关系

接口与接口之间的关系:extends 继承关系,支持多继承

3)设计理念的区别:

抽象类不能实例化,需要通过具体的子类实例化=>is a

接口不能实例化,需要通过具体的子实现类实例化=>like a

eg.

public class EatingOut {

    public static void main(String[] args) {
        //创建厨师对象
        FoodMenu cooker1 = new ChinaCooker();
        FoodMenu cooker2 = new AmricanCooker();
        //创建顾客对象
        Customer customer = new Customer(cooker1);

        //顾客点菜
        customer.order();
    }

}

//顾客
class Customer {

    /*
    Cat is a Animal,但凡满足isa的表示都可以设置为继承。
    Customer has a FoodMenu,但凡是满足hasa的表示都以属性的形式存在。
    */
    private FoodMenu foodMenu;

    public Customer() {
    }

    public Customer(FoodMenu foodMenu) {
        this.foodMenu = foodMenu;

    }

    public FoodMenu getFoodMenu() {
        return foodMenu;
    }

    public void setFoodMenu(FoodMenu foodMenu) {
        this.foodMenu = foodMenu;
    }

    public void order(){
       foodMenu.shiZiCchaoJiDan();
       foodMenu.yuXiangRouSi();
    }

}

//菜单
interface FoodMenu {

    void shiZiCchaoJiDan();

    void yuXiangRouSi();
}

//中国厨师
class ChinaCooker implements FoodMenu {

    @Override
    public void shiZiCchaoJiDan() {
        System.out.println("中餐厨师做的西红柿炒鸡蛋,得劲!");
    }

    @Override
    public void yuXiangRouSi() {
        System.out.println("中餐厨师做的鱼香肉丝,得劲!");
    }
}


//外国厨师
class AmricanCooker implements FoodMenu {

    @Override
    public void shiZiCchaoJiDan() {
        System.out.println("西餐厨师做的西红柿炒鸡蛋,蒂丽舍丝");

    }

    @Override
    public void yuXiangRouSi() {
        System.out.println("西餐厨师做的鱼香肉丝,蒂丽舍丝");
    }

}

运行结果

中餐厨师做的西红柿炒鸡蛋,得劲!
中餐厨师做的鱼香肉丝,得劲!

类型与类型之间的关系

is a(继承)、has a(关联)、like a(实现)

is a:

Cat is a Animal(猫是一个动物)

凡是能够满足is a的表示“继承关系”

A extends B

has a:

I has a Pen(我有一支笔)

凡是能够满足has a关系的表示“关联关系”

关联关系通常以“属性”的形式存在。

like a:

Cooker like a FoodMenu(厨师像一个菜单一样)

凡是能够满足like a关系的表示“实现关系”

实现关系通常是:类实现接口。

形式参数和返回值问题

如果方法的形式参数是类调用方法的时候,如何传递实际参数?

具体类,调用该方法,实际参数需要传递当前具体类的对象

抽象类,调用该方法实际参数需要传递的抽象类的子类对象 (抽象类多态)

接口 调用该方式,实际参数需要传递的是当前接口的子实现类对象(接口多态)

如果一个方法的返回值是引用类型,最终方法结束,如何返回?

具体类 :方法返回的就是当前具体类对象!

抽象类 :需要返回的是抽象类的子类对象

接口:需要返回的是该接口的子实现类对象

编译和运行
同一个包下的编译和运行:
第一种方式(手动方式)

1)需要在当前文件夹下将com文件夹以及子文件夹qf手动创建出来

2)进入dos控制台:进入当前java文件所处的目录下

javac  源文件名称(HelloWorld.java)---->HelloWorld.class 字节码文件				

3)将2)步产生的字节码文件放在1)qf子文件夹下

4)运行:带上包运行 :java 包名.类名

java com.qf.HelloWorld	
第二种方式(自动方式)

1)直接进入dos控制台,进入到指定目录下:

javac -d . java源文件(HelloWorld.java)

2)自动将包名创建出来以及包下面的字节码文件

3)运行:带上包运行 :java 包名.类名

java com.qf.HelloWorld
不同包下的编译和运行

1)将net.hsbc.Demo类导入进来

2)通过自动方式将net.hsbc.Demo---->先编译成

3)然后再通过自动方式对Test.java文件进行编译

4)运行即可java com.qf.Test

package

第一:package出现在java源文件第一行。

第二:带有包名怎么编译?javac -d . xxx.java

第三:怎么运行?java 完整类名

补充:以后说类名的时候,如果带着包名描述,表示完整类名。

如果没有带包,描述的话,表示简类名。

import

import什么时候不需要?
java.lang不需要。
同包下不需要。
其它一律都需要。

eg

	import 完整类名;
	import 包名.*;

	import java.util.Scanner; // 完整类名。

// 同学的疑问:这样是不是效率比较低。
// 这个效率不低,因为编译器在编译的时候,会自动把*变成具体的类名。
	import java.util.*;

// 想省懒劲你不能太省了。
	import java.*; 这是不允许的,因为在java语言中规定,这里的*只代表某些类的名

访问控制权限

访问控制权限都有哪些?
private私有
public公开
默认
protected受保护
以上的4个访问控制权限:控制的范围是什么?

private表示私有的,只能在本类中访问
public表示公开的,在任何位置都可以访问
"默认"表示只能在本类,以及同包下访问
protected表示只能在本类、同包、子类中访问.

访问控制修饰符本类同包子类任务位置
public可以可以可以可以
protected可以可以可以不行
默认可以可以不行不行
private可以不行不行不行

内部类

格式

内部类:

在一个类中可以定义另一个:
在类A 中定义了类B,将类B就称为类A的内部类,类A就是外部类!

成员内部类:

在一个类的成员位置中定义了另一个类
内部类可以访问外部类的成员,包括私有!

//外部类
class Outer{
    //成员变量
    public int num = 100 ;
    private int num2 = 200 ;
    class Inner{ //成员内部类
        //成员内部类的一个成员方法
        public void method(){
            System.out.println("method Inner");
            System.out.println();
            System.out.println(num2);
        }
    }
    //外部类的成员方法
    public void show(){
        //访问的成员内部类的method--->通过创建内部类对象来访问
        //method() ;错误的----访问的本类的method方法
        Inner inner = new Inner() ;
        inner.method();
    }
}
//测试
public class InnerClassDemo {
    public static void main(String[] args) {
        //创建外部类对象
        Outer outer = new Outer() ;
        outer.show();
    }
}
外部类访问内部类

1)外部类如何直接访问内部类的成员方法?

格式:

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

class Outer2{
    private int num = 20 ;
    //成员内部类
    class Inner2{
        public void show(){
            System.out.println(num);
        }
    }
    //外部类的成员方法
    public void method(){
        // 创建内部类对象访问内部类的成员方法
    }
}
//测试类
public class InnerClassDemo2 {
    public static void main(String[] args) {
        //外部类名.内部类名  对象名 =  外部类对象.内部类对象;
        //适用于:通过外部类直接访问成员内部类的成员(前提条件:当前成员内部类是一个非静态类)
        Outer2.Inner2 oi = new Outer2().new Inner2() ;
        oi.show() ;
    }
}

2)关于我们成员内部类的修饰符:

在成员内部类上面—加入private修饰:为了数据的安全性,它的访问—就要外部类的公共访问间接访问…

非static内部类不能有static修饰的变量或方法

非static的内部类,在外部类加载的时候,并不会加载它,所以它里面不能有静态变量或者静态方法。

​ 1、static类型的属性和方法,在类加载的时候就会存在于内存中。

​ 2、要使用某个类的static属性或者方法,那么这个类必须要加载到jvm中。

伪代码
     举例:
     人首先身体---身体内有心脏
           class Body{
               //内部类:心脏
             private  class Heart{  //加入private:保证数据的安全性
                      //手术
                    public void operator(){
                        System.out.println("心脏搭桥手术....") ;
                    }
               }
               //外部类提供一些公共访问
               public void method(){
                  if("如果你是外科医生"){
                       Heart heart = new Heart() ;
                       heart.operator() ;
                   }
               }
           }
           //外部类直接访问成员内部类的成员

3)如果当前成员内部类是静态的, 里面的方法无论是静态的还是非静态的,都只能访问外部类的静态成员,包括私有!
如何直接访问静态成员内部类的成员呢?
将静态的成员内部类看成是外部类的静态成员访问
直接访问方式
外部类名.内部类名 对象名 = new 外部类名.内部类名() ;

class Outer3{
    //定义非静态的成员变量
    public int num = 50 ;
    private static int num2 = 20 ;
    //定义成员内部类:静态的           ---->静态的成员内部类可以看成是外部类的静态成员
    static class Inner3{//此时类都是静态
        public void show(){
           // System.out.println(num);
            System.out.println(num2);
        }
        public static void show2(){
           // System.out.println(num);
            System.out.println(num2);
        }
    }
}
//测试类
public class InnerClassDemo3 {
    public static void main(String[] args) {
        // 外部类名.内部类名 对象名  = 外部类对象.内部类对象;
        //Outer3.Inner3 oi = new Outer3().new Inner3() ;  适用不了了
        //   外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
        Outer3.Inner3 oi = new Outer3.Inner3() ;
        oi.show();
        oi.show2() ; //静态---不推荐对象名访问
        System.out.println("------------------------------");
        //show2()的另一种方式
        Outer3.Inner3.show2(); //show2()静态方法
    }
}

To be continued…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值