Java(十)--面向对象(三)

this

public class This01 {

	//编写一个main方法
	public static void main(String[] args) {

		Dog dog1 = new Dog("大壮", 3);
		System.out.println("dog1的hashcode=" + dog1.hashCode());
		//dog1调用了 info()方法
		dog1.info();

		System.out.println("============");
		Dog dog2 = new Dog("大黄", 2);
		System.out.println("dog2的hashcode=" + dog2.hashCode());
		dog2.info();
	}
}

class Dog{ //类

	String name;
	int age;

	// public Dog(String dName, int  dAge){//构造器
	// 	name = dName;
	// 	age = dAge;
	// }
	//如果我们构造器的形参,能够直接写成属性名,就更好了
	//但是出现了一个问题,根据变量的作用域原则
	//构造器的name 是局部变量,而不是属性
	//构造器的age  是局部变量,而不是属性
	//==> 引出this关键字来解决
	public Dog(String name, int  age){//构造器
		//this.name 就是当前对象的属性name
		this.name = name;
		//this.age 就是当前对象的属性age
		this.age = age;
		System.out.println("this.hashCode=" + this.hashCode());
	}

	public void info(){//成员方法,输出属性x信息
		System.out.println("this.hashCode=" + this.hashCode());
		System.out.println(name + "\t" + age + "\t");
	}
}
//假设有一个教师类 Teacher 的定义如下:

    public class Teacher {
        private String name;    // 教师名称
        private double salary;    // 工资
        private int age;    // 年龄
    }

在上述代码中 name、salary 和 age 的作用域是 private,因此在类外部无法对它们的值进行设置。
为了解决这个问题,可以为 Teacher 类添加一个构造方法,然后在构造方法中传递参数进行修改。代码如下:

    // 创建构造方法,为上面的3个属性赋初始值
    public Teacher(String name,double salary,int age) {
        this.name = name;    // 设置教师名称
        this.salary = salary;    // 设置教师工资
        this.age = age;    // 设置教师年龄
    }

在 Teacher 类的构造方法中使用了 this 关键字对属性 name、salary 和 age 赋值,this 表示当前对象。
this.name=name语句表示一个赋值语句,等号左边的 this.name 是指当前对象具有的变量 name,等号右边的 name 表示参数传递过来的数值。

测试类:
 	创建一个 main() 方法对 Teacher 类进行测试,代码如下:

    public static void main(String[] args) {
        Teacher teacher = new Teacher("王刚",5000.0,45);
        System.out.println("教师信息如下:");
        System.out.println("教师名称:"+teacher.name+"\n教师工资:"+teacher.salary+"\n教师年龄:"+teacher.age);
    }

运行该程序,输出的结果如下所示。

教师信息如下:
教师名称:王刚
教师工资:5000.0
教师年龄:45
//需求:假设定义了一个 Dog 类,这个 Dog 对象的 run( ) 方法需要调用它的 jump( ) 方法;


public class Dog {
    // 定义一个jump()方法
    public void jump() {
        System.out.println("正在执行jump方法");
    }


// 定义一个run()方法,run()方法需要借助jump()方法
public void run() {
    // 使用this引用调用run()方法的对象
    this.jump();
    System.out.println("正在执行run方法");
}
}

测试类:
    public class DogTest {
        public static void main(String[] args) {
            // 创建Dog对象
            Dog dog = new Dog();

            // 调用Dog对象的run()方法
            dog.run();
        }
    }


说明:
1)在 run( ) 方法中调用 jump( ) 方法时是否一定需要一个 Dog 对象?

答案是肯定的,因为没有使用 static 修饰的成员变量和方法都必须使用对象来调用。

2)是否一定需要重新创建一个 Dog 对象?

不一定,因为当程序调用 run( ) 方法时,一定会提供一个 Dog 对象,这样就可以直接使用这个已经存在的 Dog 对象,而无须重新创建新的 Dog 对象。因此需要在 run() 方法中获得调用该方法的对象,通过 this 关键字就可以满足这个要求。

this 可以代表任何对象,当 this 出现在某个方法体中时,它所代表的对象是不确定的,但它的类型是确定的,它所代表的只能是当前类的实例。
只有当这个方法被调用时,它所代表的对象才被确定下来,谁在调用这个方法,this 就代表谁。

super


static


final

//属性赋值

class AA {

    public final double TAX_RATE = 0.08;//1.定义时赋值
    public final double TAX_RATE2 ;
    public final double TAX_RATE3 ;

    public AA() {//构造器中赋值
        TAX_RATE2 = 1.1;
    }
    {//在代码块赋值
        TAX_RATE3 = 8.8;
    }
}

//static修饰时

class BB {
    /*
    如果final修饰的属性是静态的,则初始化的位置只能是
    1 定义时  2 在静态代码块 不能在构造器中赋值。
     */
    public static final double TAX_RATE = 99.9;
    public static final double TAX_RATE2 ;

    static {
        TAX_RATE2 = 3.3;
    }
}



//方法中使用
public class Test {
    public static void main(String[] args) {
                new EE().cal();
            }
        }

//如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承,仍然遵守继承的机制.
class DD {
    public final void cal() {
        System.out.println("cal()方法");
    }
}

class EE extends DD { }

native

表示原生的

表示非Java语言实现的;但是使用者可以把它当做Java的方法或成员使用;


new 

表示创建对象;

和构造器一起


接口(interface)

    接口由全局常量和公共的抽象方法所组成;

  •         一种更加特殊的“抽象类”
  •         接口的所有方法是 public方法,抽象方法的abstract可以省略不写
  •         接口的成员没有执行体

    接口的修饰符 只能是 public 和默认,与类的修饰符是一样的;

    接口中属性

  •         访问形式:            接口名.属性名
  •         只能是final,且是public static final修饰符;            接口中定义的变量必须初始化

    接口没有构造方法,不能被实例化

    接口可以继承接口,而且可以继承多个接口

    接口的应用

  •         (1)代理模式(Proxy)
  •         (2)工厂模式

//接口的属性
public class Interface_01 {
	public static void main(String[] args) {
		new C().pX(); //0 1
	}
}

interface A {  // 1min 看看
	int x = 0;
}  //想到 等价 public static final int x = 0;

class B {
	int x = 1;
} //普通属性


class C extends B implements A {
	public void pX() {
		//System.out.println(x); //错误,原因不明确x
		//可以明确的指定x
		//访问接口的 x 就使用 A.x
		//访问父类的 x 就使用 super.x
		System.out.println(A.x + " " + super.x);
	}
}


//接口与类的关系
public class InterfaceDetail01 {
    public static void main(String[] args) {
        //new IA();
    }
}

//1.接口不能被实例化
//2.接口中所有的方法是 public方法,  接口中抽象方法,可以不用abstract 修饰
//3.一个普通类实现接口,就必须将该接口的所有方法都实现
//4.抽象类去实现接口时,可以不实现接口的抽象方法

interface IA {
    void say();//修饰符 public protected 默认 private
    void hi();
}

class Cat implements IA{
    @Override
    public void say() {

    }

    @Override
    public void hi() {

    }
}

abstract class Tiger implements  IA {

}
//多态传递
public class InterfacePolyPass {
    public static void main(String[] args) {

//接口类型的变量可以指向,实现了该接口的类的对象实例

        IG ig = new Teacher();

//如果IG 继承了 IH 接口,而Teacher 类实现了 IG接口,实际上就相当于 Teacher 类也实现了 IH接口,这就是所谓的 接口多态传递现象.

        IH ih = new Teacher();
    }
}

interface IH {
    void hi();
}

interface IG extends IH{ }

class Teacher implements IG {
    @Override
    public void hi() {
    }
}



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

        //接口的多态体现
        //接口类型的变量 if01 可以指向 实现了IF接口类的对象实例
        IF if01 = new Monster();
        if01 = new Car();

        //继承体现的多态
        //父类类型的变量 a 可以指向 继承AAA的子类的对象实例
        AAA a = new BBB();
        a = new CCC();
    }
}

interface IF {}

class Monster implements IF{}

class Car implements  IF{}

class AAA {

}
class BBB extends AAA {}
class CCC extends AAA {}

为什么要声明接口?

  •     (1)解决Java的单继承
  •     (2)多个不相关的类,可能具有共同的行为特征,这样的行为特征,就可以提取成一个接口; 补充了类与类之间的关系,对象与对象之间的关系,has -a 的关系,like -a的关系;
//声明
//接口就是给出一些没有显示的方法,封装到一起,到某个类要使用时,再根据具体情况把这些方法写出来

[public] interface  接口名{

    // 接口体,其中可以包含定义常量和声明方法
    [public] [static] [final] type constant_name = value;    // 定义常量

    [public] [abstract] returnType method_name(parameter_list);    // 声明方法
}



//实现接口

【修饰符】 class 实现类名  implements 接口名1,接口名2。。。{
自己的属性
自己的方法
必须实现的接口的抽象方法
}


//如果继承一个类与实现接口同时存在,那么要先继承后实现

【修饰符】 class 子类  extends 父类  implements 接口名1,接口名2。。。{
}

比较


抽象类(abstract)

指一个类中没有包含足够的信息来描绘一个具体的对象;

抽象方法只有声明没有实现;

  •     没有方法体
  •     必须存在于抽象类中

抽象类的价值更多在于设计,设计者设计好后,让子类继承并实现抽象类;

如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为 abstract 类;

抽象类的本质还是类,所以可以有类的各种成员;

  •     例如:非抽象方法,构造器,静态属性等

一个抽象类中,可以有 0~n 个抽象方法,以及 0~n 个具体方法。

//应用

abstract public class Template { //抽象类-模板设计模式

    public abstract void job();//抽象方法

    public void calculateTime() {//实现方法,调用 job 方法
        //得到开始的时间
        long start = System.currentTimeMillis();
        job(); //动态绑定机制
        //得的结束的时间
        long end = System.currentTimeMillis();
        System.out.println("任务执行时间 " + (end - start));
    }
}



public class A extends Template{
    @Override
    public void job() {
        long num = 0;
        for (long i = 1; i <= 800000; i++) {
            num += i;
        }
    }
}


public class B extends Template {
    @Override
    public void job() {
        long num = 0;
        for (long i = 1; i <= 50000; i++) {
            num += i;
        }
    }
}


public class Abstract01 {
    public static void main(String[] args) {
        A a = new A();
        a.calculateTime();

        B b = new B();
        b.calculateTime();
    }
}

package(打包)


权限修饰符/访问修饰符

定义:  用来控制方法和属性(成员变量)的访问权限(范围);

说明:

  •     只有 缺省(default)和 public 可以修饰类
  •         protected和private可以修饰内部类
  •     可用来修饰类中属性、成员方法及类

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hahaha2221

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值