流年似水博客开通了,本站主要是写关于Web和大数据方面内容,正在更新中,欢迎大家光临!
  1. 文章:97 篇
  2. 总浏览:35,109 次
  3. 评论:22条
  4. 最后更新:2020-06-08
  5. 分类目录:39 个

Java之面向对象(继承、super关键字、方法重写、多态、Object类)

Java l, xy 177℃ 0评论

  1. 继承

(1)      概念:类在逻辑上存在一种 is a 关系的类,可以使用继承

(2)      继承的优点

1           提高代码的复用性(重用性)

2           提高了代码的扩展性(可维护性)

(3)      语法

          Class A extends B {

 

}

(4)      特点

1           javaObject是所有类(除它本身以外的)的父类(基类或者超类)

2           Java中类的继承是单继承(一个类只能有一个直接父类),但是接口可以多继承

3           子类可以继承父类中所有的属性和方法(不包括构造方法)如果父类中属性和方法的使用private(私有化)(跨包使用默认修饰)修饰,则子类中不能直接访问   --- 这一点和以前学习的不太一样

4           子类不能继承父类的构造方法

5           如果一个类有许多父类,当初始化该类的时候,默认情况下回默认调用父类的无参构造方法。同时也会优先加载父类到方法区。

6           如果父类中没有无参的构造方法,而子类的构造方法中也没有显示的调用父类的有参构造,将会出现编译错误。---找不到父类的无参构造方法

 

 

 

(5)      使用到的关键字

1           Extends:继承的关键字

1)         注意:

  1. Extends关键字后面只能写一个父类,因为java只支持单继承

2           Super

1)         作用:

  1. 在继承关系中,可以调用父类(包括间接父类)的非私有化成员(属性、方法)、构造方法

a)         调用属性:Super.属性名

b)        调用成员方法:Super.方法名(【参数列表】);

c)         调用父类构造方法:Super(【参数列表】


package cn.cupcat;

class Person{
/**
* 年龄,这是测试,没有使用private修饰
* */
protected int age;
/**
* 姓名
* */
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
/**
* 父类无参构造
* */
public Person(){

}
/**
* 父类有参构造
* */
public Person(String name){
this.name = name;
}

}
class Student extends Person{
/**
* 身高
* */
private double height;
/**
* 测试调用父类方法和属性
* */
private void test(){
//调用父类方法
super.getName();
//调用父类属性,如果父类属性被private修饰,子类将无法直接调用属性
//但是可以使用父类提供的公用方法访问
int age = super.age;
}
/**
* 测试调用父类构造方法
* */
public Student(double height,String name) {
//演示调用父类有参构造
super(name);
this.height = height;
}
}

 

  1. 可以解决父类中(直接父类和间接父类)变量名重名调用的问题

 

2)         使用前提:一定要继承关系

3)         特点:

  1. 默认情况下,JVM都会在子类所有的构造方法的第一条显示语句之前调用父类的无参构造函数。若有构造函数显示的调用本类的其他构造函数(this调用)或者显式的调用父类的构造器(super调用),则JVM将不会自动调用父类无参构造方法。
  2. Super关键字不能和this关键字一起使用(因为两者都要求存在构造方法的第一条语句,相互冲突)

 


package cn.cupcat;

class Father{
private String name;

public Father(String name){
this.name = name;
}
/**
* 无参构造
* */
public Father(){}
}


class Son extends Father{

private int age;

public Son(){

}
public Son(int age){
this.age = age;
}
/**
* 演示super 和 this 不能同时在一起
* */
public Son(int age,String name){
// 编译报错:
super(name);
this(age);
}

}

  1. Super调用父类构造方法的时候,只能在子类的构造方法中使用,否则编译错误。
  2. Super调用父类的方法、属性可以在合法的任意位置调用。
  3. 若子类的属性与父类重名,可以使用super显示的调用父类的属性。子类复写父类方法时,也可以使用super显示调用父类方法。
  4. Super关键不仅可以调用直接父类的属性、方法、构造方法,还可以调用间接父类的属性、方法、构造器,若直接父类、和间接父类中出现多个重名属性,但是还想调用其间接父类的属性,则需要的直接父类使用方法来封装。调用都遵循就近原则。 




package cn.cupcat;

public class OverrideDemo {

public static void main(String[] args) {
Son son = new Son();
son.test();
}
}

class GrandParent{
String name = "我是爷爷";
}

class Father extends GrandParent{
String name = "我是爸爸";

/*
* 获取Father类父类的name属性
* */
public String getParentName(){
return super.name;
}
}

class Son extends Father{
String name = "我是儿子";

/**
* 测试子类与直接父类、间接父类出现属性的访问
* */
public void test(){
System.out.println("-----------------本类属性------------------------");
// 访问本类name 属性
System.out.println(name);
System.out.println(this.name);
System.out.println(Son.this.name);

System.out.println("-----------------直接类属性------------------------");
//访问直接父类的name属性,在本案例中就是访问Father中的name属性
System.out.println(super.name);
System.out.println(Son.super.name);

System.out.println("-----------------间接类属性------------------------");
//访问间接父类的name属性,本案例中就是访问GrandParent的name属性
System.out.println(super.getParentName());

}
}

打印结果:
-----------------本类属性------------------------
我是儿子
我是儿子
我是儿子
-----------------直接类属性------------------------
我是爸爸
我是爸爸
-----------------间接类属性------------------------
我是爷爷

  1. Super也可直接调用间接父类的属性和方法(前提是直接父类中没有跟其重名的属性和方法),直到追溯到Object类为止



package cn.cupcat;

public class OverrideDemo {

public static void main(String[] args) {
Son son = new Son();
son.test();
}
}

class GrandParent{
String name = "我是爷爷";
}

class Father extends GrandParent{
//这里注释了
//String name = "我是爸爸";

/**
* 获取Father类父类的name属性
* */
public String getParentName(){
return super.name;
}
}

class Son extends Father{
String name = "我是儿子";

/**
* 测试子类与直接父类、间接父类出现属性的访问
* */
public void test(){
System.out.println("-----------------本类属性------------------------");
// 访问本类name 属性
System.out.println(name);
System.out.println(this.name);
System.out.println(Son.this.name);

System.out.println("-----------------直接类属性------------------------");
//访问直接父类的name属性,在本案例中就是访问Father中的name属性
System.out.println(super.name);
System.out.println(Son.super.name);

System.out.println("-----------------间接类属性------------------------");
//访问间接父类的name属性,本案例中就是访问GrandParent的name属性
System.out.println(super.getParentName());

}
}

打印结果:
-----------------本类属性------------------------
我是儿子
我是儿子
我是儿子
-----------------直接类属性------------------------
我是爷爷
我是爷爷
-----------------间接类属性------------------------
我是爷爷

 

(6)      Super 和 this 对比 : 下面说的父类,包括直接父类和间接父类

 

意义

子类属性和方法

父类属性和方法

子类构造方法

父类构造方法

是否可以一起使用

两则调用关系

Super

父类引用

不可以

可以(就近原则)

不可以

可以

不可以

This代表的构造函数里面一定调用super代表的构造函数

This

当前对象

可以

可以(不出现重名),就近原则

可以

不可以

 

(7)      方法重写

1      前提:存在继承或者实现关系

2      要求:

1)  子类的方法签名(方法名、参数列表)必须和父类中对应方法相同

2)  JDK1.4以前要求返回值类型必须相同。JDK5以后要求返回值也可以是父类方法返回值的子类类型

3)   子类中的访问修饰符的权限必须大于或者等于父类中的权限

4)    父类方法中没有抛出异常,子类复写是也不应该抛出异常

5)   父类方法中抛出异常,子类中只能抛出父类方法抛出的异常或者父类抛出异常的子类

 

(8)      重写与重载对比

 

英文

方法名

参数列表

返回值

修饰符

抛出异常

本类

子类

重载

Overload

相同

必须不同

无关

无关

无关

重写

Override

相同

一定相同

相同,或者是其子类

相同,或者权限大于

相同,或者是其子类

  1. 多态

(1)      接口

1           概念:描述一组功能的集合,是抽象的。

2           语法:interface 接口名{

}

3           作用:

1)         提供一个同一规范

2)         方便功能扩展

4           特点:

1)         接口中所有的成员都是公共常量(缺省使用 Public final 修饰)

2)         JDK8以前,所有的方法都是修饰方法(缺省使用 public abstract 修饰)

3)         JDK8以后,可以定义使用default关键字默认方法(可以有默认实现)

4)         JDK以后,可以定义静态的方法,使用接口.静态方法名(【参数列表】)调用;

(2)      多态的概念:

1           父类的引用指向了子类的对象

(3)      多态的前提

1           存在继承或者实现关系

(4)      多态的形式

1           父类类型  对象名  = new 子类类型();

2           特点:

1)         编译看左边,运行看右边

2)         可以调用父类中的所有成员(方法、变量),不能调用子类中的特有成员,但是在运行的时候调用的时子类的方法。

 

注意: 属性没有重写,属性的调用要看编译时期的类型

 

(5)      转型

1           (向上转型)自动转型

 Animal a = new Dog();

2           (向下转型)强制转换

 Dog d = (Dog)a;

3           转换原则

1)         强制转换只能转换父类引用指向的时本类的对象,否则会报运行异常:TypeCastException

2)         转换成子类以后,就可以调用子类的左右方法。

 

(6)      多态的好处

1           提高了代码的复用性

2           大大的提高了代码的扩展性和维护性

(7)      多态的应用

1           多态数组

1)         数组定义的父类类型,可以存在子类类型的元素


Object[] objects = {"1", 1, 3};
Object[] objs = new Object[]{"你好", new Integer(3)};

2)         数组定义的父类类型,可以new子类类型


Object[] objects1 = new String[]{"1","2"};
Object[] objects2 = new Integer[]{1,2};

 

2           多态参数

1)         方法中父类类型的参数,可以传子类类型

(8)      特点:

1          在多态中除了实例方法是调用的子类的以外,其他调用全是调用父类的。

 

补充:

instanceOf 比较操作符,用于判断某个对象的实际允许类型是否为XX类型或XX类型的子类型

 

  1. Object类型

(1)      学习一个新类的步骤

1           看包

2           看类的说明

3           看构造方法

4           看具体方法

5           写案例

(2)      Object中的方法

1           HashCode()

2           Public boolean Equals()

3           toString()

4           Finalize()

5           Wait()

6           getClass()

7           Notify()

8           Clone()

9           notifyAll()


 

###equals方法 ★

 

一、==equals的对比

 

  == :比较运算符,既可以判断基本类型,又可以判断引用类型

   如果判断基本类型,判断的是值是否相等。示例:int i=10; double d=10.0;    i==d true

              如果判断引用类型,判断的是地址是否相等.

equals: Object类中的方法,只能判断引用类型

  判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等,比如StringInteger

  public boolean equals(Object obj){

  return this==obj;

  }

二、如何重写equals方法?

 


/**
* 功能:判断两个Person对象的内容是否相等
* 如果两个Person对象的各个属性值都一样,结果为true,反之为false。
* p1.equals(p2) 相当于 this vs obj
*/

public boolean equals(Object obj){
if(this==obj)//①提高效率
return true;
//②判断实参的运行类型,提高容错性
if(!(obj instanceof Person))
return false;
//③向下转型
Person p =(Person) obj;
//④判断内容是否相等
return name.equals(p.name)&&age==p.age&&gender==p.gender;
}

三、hashCode方法

好处:提高具有哈希结构的容器的效率!

1、两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!

2、两个引用,如果指向的是不同对象,则哈希值是不一样的

哈希值主要根据地址号来的!

四、toString方法 ★

特点:

默认返回:全类名+@+哈希值的十六进制

    子类往往重写toString方法,用于返回对象的属性信息

五、如何重写toString方法?


public String toString(){

return name+"\t"+age+"\t"+gender;

}

使用:

打印对象或拼接对象时,都会自动调用该对象的toString形式

六、finalize方法

功能:当对象被回收时,系统自动调用该对象的finalize方法。子类可以重写该方法,做一些释放资源的操作

1、垃圾回收器回收什么?

  无用对象。(当对象没有任何引用指向时)

2、垃圾回收器回收时机?

不确定的

3、加速垃圾回收器回收时机?

    System.gc(); 

  1. 重大发现:

(1)      在类中如果有一个方法的参数类型是本类类型,那么这个方法的形参可以直接调用本类中私有化的属性--------------以前一直不知道


package cn.cupcat;

public class Person {

private String name;

public int compare(Person person){

//这里不会编译错误
System.out.println(person.name);
return -1;
}
}

转载请注明:流年似水 » Java之面向对象(继承、super关键字、方法重写、多态、Object类)

喜欢 (0)or分享 (0)

Warning: copy(https://cn.gravatar.com/avatar/?s=54&d=%2Fwp-content%2Fthemes%2Fyusi1.0%2Fimg%2Fdefault.png&r=g): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 239

Warning: copy(/wp-content/themes/yusi1.0/img/default.png): failed to open stream: No such file or directory in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 243
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址