java高级类_Java高级类特性(一)

权限类内同包不同包子类不同包非子类

private

×

×

×

default

×

×

protected

×

public

四、super关键字的使用

package com.test.java;

/*

* super可以用来修饰属性、方法、构造器

* 1)当子类与父类中有同名的属性时,可以通过"super.属性"显式的调用父类中声明的属性。用"this.属性"调用子类中声明的属性

* 2)当子类重写父类的方法以后,在子类中想再显式的调用父类的被重写的方法,需要用"super.方法来调用"

* 3)super修饰构造器:通过在子类中使用"super(形参列表)"来显式的调用父类的构造器

* >在构造器内部,"super(形参列表)"必须要声明在首行

* >在构造器内部,"this.(形参列表)"与"super(形参列表)"只能出现一个

* >当构造器中,不显式的调用this()或者super()其中任何一个,默认调用的是父类的空参构造器

* 如果父类没有声明空参构造器,或者只声明了带参数的构造器(这时空参构造器自动作废),在子类

* 中会报错

* 建议:在设计一个类时,尽量提供一个空参构造器。

*/

public class Person {

public String name;

public Person() {//父类构造器

this.name = "Father";

System.out.println(this.name);

}

public void eat() {

System.out.println("父类吃饭");

}

}

class Student extends Person{

public String name;

public Student() {//子类构造器,经过main方法测试,调用子类构造器之前会自动调用父类构造器

//相当于这里有一个 Super();

this.name = "Son";

super.name = "SuperFather";//在子类中调用父类的

System.out.println(this.name+super.name);

}

public void eat() {

System.out.println("子类吃饭");

super.eat();//在子类中用super调用父类的重名方法,重写(覆盖)并不等于将父类的方法删除掉。

}

}

五、子类对象实例化

class Creature{

public Creature(){

System.out.println("Creature无参数的构造器");

}

}

class Animal extends Creature{

public Animal(String name){

System.out.println("Animal带一个参数的构造器,该动物的name为" + name);

}

public Animal(String name , int age){

this(name);

System.out.println("Animal带两个参数的构造器,其age为" + age);

}

}

public class Wolf extends Animal{

public Wolf(){

super("灰太狼", 3);

System.out.println("Wolf无参数的构造器");

}

public static void main(String[] args){

new Wolf();

} }

从创建Wolf对象开始,调用Wolf构造器,Wolf构造器调用父类Animal的两个参数的构造器,两个参数的构造器再调用一个参数的构造器,一个参数的构造器再调用父类Creature的构造器,Creature构造器调用Object类中的构造器,然后再逆向执行回来,最后一个被调用的构造器最先执行,依次向下执行构造器中的内容,像对象中的toString方法等就是再Object类中的某个方法,任何一个类调用构造器都会以最后一个Object类结束。

六、多态性

package com.xijian.java;

/*

* 多态的应用举例

* 总结:通过向上转型来引用父类方法(在子类未重写方法的前提下),通过向下转型来引用子类独有的方法

* 向下转型实际就是在栈空间声明一个子类引用类型的变量指向栈空间的父类引用对象,通过父类引用对象进而指向堆空间,对对象进行操作。

* 访问权限是由引用变量类型决定的。

*/

public class TestAnimal {

public static void main(String[] args) {

Animal a = new Dog();//可以扩大对象被调用的权限

Animal b = new Cat();//可以扩大对象被调用的权限

TestAnimal test = new TestAnimal();

test.func(a);

test.func(b);

}

public void func(Animal a) {

a.eat();

a.jump();

if(a instanceof Dog) {

Dog d = (Dog)a;//向下转型,用新的引用类型去引用子类存在而父类不存在的方法

d.say();

}

if(a instanceof Cat) {

Cat c = (Cat)a;//向下转型,用新的引用类型去引用子类存在而父类不存在的方法

c.say();

c.name = "1";

System.out.println(a.name);//通过测试可以看出,向下转型使用新的引用类型可以对子类对象进行操作

}

}

}

class Animal{

String name;

int age;

public void eat() {

System.out.println("进食");

}

public void jump() {

System.out.println("jump");

}

}

class Dog extends Animal{

public void eat() {

System.out.println("狗进食");

}

public void jump() {

System.out.println("狗急跳墙");

}

public void say() {

System.out.println("狗叫");

}

}

class Cat extends Animal{

public void eat() {

System.out.println("猫进食");

}

public void jump() {

System.out.println("猫跳");

}

public void say() {

System.out.println("猫叫");

}

}

多态性:多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

1)如果我们定义了一个指向子类的父类引用类型,那么它除了能够引用父类的共性外,还可以使用子类强大的功能,这就是向上转型。

父类名称 引用对象名称 = new 子类对象名称();

指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。()

2)如果在向上转型之后想访问子类中独有的方法,需要向下转型,向下转型实际就是在栈空间声明一个子类引用类型的变量指向栈空间的父类引用对象,通过父类引用对象进而指向堆空间,对对象进行操作。

子类名称 新引用对象名称 = (子类名称)需转型的对象名;

3)子类对象的多态性,并不适用于属性!

在调用属性的时候,只是看的是调用对象的引用类型,如果这个对象的引用类型是父类的,那么调父类的属性,如果是个子类的引用类型,则调子类对应的属性,并不存在多态性。

4)判断对象属于哪种类型的

if(obj instanceof class){}

其返回true情况如下

1.obj是class类的对象

2.obj是class类子类的对象

多态性在Java上有两种体现

①方法的重载和重写:同名方法可以通过形参列表的不同和子父类的继承关系来同时显示。

②对象的多态性:子类的对象可以赋给父类/父接口的引用。

七、所有的类的顶级类Object

package com.xijian.java;

public class Testequals {

public static void main(String[] args) {

//==

//1.基本数据类型:根据基本数据类型的值判断是否相等。相等返回true,否则返回false

//注:两端数据类型可以不同,在不同的情况下也可以返回true

int i = 12;

int j = 12;

System.out.println(i==j);//true

char c = 12;

System.out.println(i==c);//true

float f = 12.0F;

System.out.println(i==f);//true

int k = 65;

char a = 'A';

System.out.println(k==a);//true

//2.引用数据类型:比较引用类型变量的地址值是否相等。

Object obj1 = new Object();

Object obj2 = new Object();

Object obj3 = new Object();

obj3 = obj1;

System.out.println(obj1==obj2);//false

System.out.println(obj1==obj3);//true

//equals():①只能处理引用类型对象,并且比较的是两个对象的地址值是否相等

System.out.println(obj1.equals(obj2));

System.out.println(obj1.equals(obj3));

//像String类 包装类 File类 Date类重写了Object类里的equals方法

//比较的是两个对象中的具体内容是否相同

String str1 = new String("AA");

String str2 = new String("AA");

System.out.println(str1.equals(str2));//true

}

}

Object是Java中所有类的顶级类。

①在Java中,==表示等于,=表示赋值。

当==两侧比较的是基本数据类型时,由基本数据类型的值判断二者是否相等,相等则返回true,不等在返回false。需要注意的是,两侧的基本数据类型即使类型不同,也会返回true,如:int i =65,char j=12;char a ='A';则i==j==a全部返回true。

当两侧是引用数据类型时,两侧比较的是引用变量的地址值,相等返回true,不等返回false。

②equals方法

equals方法只可以处理引用数据类型的变量,在object类中,equals方法仍然是比较两个引用变量的地址值是否相同;所以要想用equals方法比较object类子类的实体内容,就必须要重写object类的equals方法。

③String类在内存中的分析

翻看String类的源代码我们可以知道:它是不可继承的(final修饰类),线程安全的(?????),值不可变(两个成员变量都有final修饰,指针可变),本质上是一个字符数组。

我们知道创建string类对象的时候,一般由三种方式:

使用关键字new,如:String s1 = new String(“myString”);

直接定义,如:String s1 = “myString”;

串联生成,如:String s1 = “my” + “String”

第一种使用关键字new创建的String类对象时,编译程序回先在字符串常量池中查看有没有“myString”这个字符串,若有,则在堆中开辟一块空间存放new出来的实例,指向常量池中的"myString",在栈中开辟一块区域存放s1这个引用变量,指向堆中的new出来的实例;若没有,则在常量池中创建一个"myString"字符串。

第二种方式直接定义过程:在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中开辟一个内存空间存放“myString”;如果存在的话,则不用重新开辟空间。然后在栈中开辟一块空间,命名为“s1”,存放的值为常量池中“myString”的内存地址

第三种,改变的不是字符串,而是相当于重新创建了一个新的字符串,重新有一个地址值。

相对于new出来的字符串来说,直接赋值的方式效率好,因为它只在字符串常量池开辟了一个内存空间,而new出来的相当于开辟了两个内存空间,耗费内存。

④toString()方法的使用

当我们打印一个引用变量的对象时,默认会调用这个对象的toString方法。

如果对象所在的类没有重写Object中的toString方法,那么调用的就是Object中的toString方法,打印出全类名+@+首地址值。

八、包装类

将8个基础数据类型包装成类之后,就可以调用类中的方法来处理这些数据了。

基本数据类型、包装类、String类之间的转换问题

原则:转换成谁,去谁里边找转换方法或者构造器。

① 基本数据类型和包装数据类型之间的转换:JDK5.0之后加入了自动装箱和拆箱的功能。

②基本/包装数据类型和String数据类型之间的转换

String-->包装数据类型:Integer.parseInt(str)

包装数据类型-->String:i+“ ”

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值