继承及多态的理解

二维数组:

格式:

数据类型[][] 数组名=new 数据类型[m][n];

m指的是当前二维数组中的一维数组的数量。

n指的是每一个一维数组中元素的数量。

二维数组中定义的方式还有两种情况:

数据类型[] 数组名[]=new 数据类型[m][n]

数据类型 数组名[][]=new 数据类型[m][n]

例如:

package com.test;
public class DomeArr {
 
public static void main(String[] args) {

int[][] arr=new int[2][3];
System.out.println(arr); //运行结果为[[I@70dea4e
System.out.println(arr[0][0]); //运行结果为0
System.out.println(arr[1][2]); //运行结果为0
}
}

由上例可得,当你在定义一个二维数组的时候,并没有完全定义其中的元素值,输出时系统会默认为0,当你输出整个二维数组或者其中的任何的一个一维数组,输出的都是地址符。

二维数组的第二种定义方法:

//main方法中

int[][] arr=new int[2][];

//通过动态赋值的方式去给其中的一维数组定义其中的长度

arr[0]=new int[2];

arr[1]=new int[3];

System.out.println(arr[1][2]);

二维数组的第三种定义方式:

//main方法中

Int[][] arr={{1,2,3},{4,5},{7,8,9}};

System.out.println(arr[2][1]);

这种方法是最简单的方法了

在上周已经说过了一维数组的遍历,现在来看看二维数组的遍历

二维数组的遍历

package com.test;
public class DomeArr {

public static void main(String[] args) {
 
int[][] arr= {{1,4,7},{2,5,8},{3,6,9}};
TextArr(arr); //调用新方法中的循环
}
//创建一个新方法
public static void TextArr(int[][] arr) {
for(int x=0;x<arr.length;x++) { //代表一维数组的数量
for(int y=0;y<arr[x].length;y++) { //代表一维数组的长度
System.out.print(arr[x][y]+" ");
}
}
} 
}

代码块

代码块:用{}括起来的代码,统称为代码块;

代码块分为三种:

1)局部代码块:就是在方法内的局部位置

作用:给变量限定他的使用范围,在代码块中无法调用变量。

例如:

public static void main(String[] args) {

{

int a=23;

System.out.println(a);

}

System.out.println(a);//在这里就会报错,无法访问a的值

2)构造代码块:在类中方法外的成员位置,用{}括起来。

切记:在执行构造方法之前,先执行构造代码块

3)静态代码块:依旧在成员位置,用static修饰

作用:给类进行初始化的

切记:静态代码块只能执行一次

那么以上三种代码块的优先级是什么呢?

答:静态代码块>构造代码块>局部代码块

 

 

继承

面向对象的三个基本特征:封装、继承、多态。

在上周的总结中已经提到了封装,这周将会继续介绍继承和多态。

继承:顾名思义就是得到被继承者的东西。比如儿子可以得到父亲的东西,并且可以去使用它。

关键字:extends

特点1)子类可以继承父类的所有东西(包括私有变量,成员变量,成员方法)。但是切记子类不能直接使用父类中私有的东西,必须通过父类的公共访问方法或者setxxxgetxxx的方法才可以间接的去调用,在下面的例子我会写到。

2)继承不能多继承,只能单继承(class 子类extends 父类,母类:这样写是错误的,不能这样去写),但是可以多层继承。

格式class 子类 extends 父类{

....

}

例如

package com.practice01;
class person{ 
private String name;
private int age;
 
//在这里是通过公共访问的方式在父类的成员方法中调用并定义私有变量,然后通过在主函数中,创建子类的对象调用父类的方法就可以去得到父类的私有变量
public void sleep() {
System.out.println(name="张三"); System.out.println(age=16);  
} 
//以下是通过setxxx和getxxx的方式去调用父类中的私有变量 
public person() {
super(); //快键键:shift+Alt+s+c

}

public person(String name, int age) {
super();
this.name = name; //快键键:shift+Alt+s+o
this.age = age;
}

 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
 
public int getAge() { //快键键:shift+Alt+s+r
return age;
}
 
public void setAge(int age) {
this.age = age;
}
public void method() {
System.out.println("学生在上晚自习");
}
public void show() {
System.out.println("老师在上课");
}
public void work() {
System.out.println("工人在上班");
}
}

class student1 extends person{

}
public class Dome01 {
public static void main(String[] args) {
student1 s=new student1(); //创建子类的类对象去调用
s.sleep();
s.work();
System.out.println("--------------------");
s.setName("迪丽热巴");
s.setAge(21);
System.out.println(s.getName()+"-----"+s.getAge());
}
}

多层继承

//在这里father继承person

class father extends person{

public void eat{

System.out.println(爸爸爱吃米饭)

}

}

//在这里student1继承father

class student1 extends father{

 

}

//然后在主函数中你就可以向上面一样通过子类的类方法去调用father类和person类了。

当父类中的成员方法被私有化时,可以在父类中在创建一个公有public的方法去访问私有方法,例如:

package com.test;
class father{
private void emerge() {
System.out.println("emerge的意思是浮现,出现");
}
public void explode() {
emerge(); //这里去访问私有的emerge方法
}
}
class son extends father{
public void compound() {
 
}
}
public class Dome01 {
public static void main(String[] args) {
son s=new son(); 
s.explode(); //然后在这里可以进行调用输出
 
}
}

友情提示:如下所示,当父类和子类中的变量名一致时,采取就近原则输出,首先先看子类的局部位置,有的话输出,没有的话再去子类的成员位置寻找,如果还没有的话,再去父类的成员位置去寻找,有的话输出,如果还没有的话,就会报错。

package com.test;
class father{
int num=150;
}
class son extends father{
public void compound() {
 int num=15;
 System.out.println(num);
}
}
public class Dome01 {
public static void main(String[] args) {
son s=new son();
s.compound();
}
}

以上代码输出结果是:15

友情依旧提示:如下所示,当子类与父类中的局部变量或者方法变量名称一致时,而你又想输出子类的方法变量和父类的方法变量时,不同担心,superthis就起作用了。

package com.test;
class father{
int num=150;
}
class son extends father{
int num=100;
public void compound() {
 
int num=15;
System.out.println(num);
System.out.println(this.num); //this代表了子类的类对象,可以去调 //用子类的方法变量
 
System.out.println(super.num);//super代表的是父类引用,可以去调 //用父类的方法变量

}
}
public class Dome01 {
public static void main(String[] args) {
son s=new son();
s.compound();
}
}

接下来介绍thissuper关键字的用法:

子类不可以直接继承父类中的构造方法,但是可以通过thissuper进行访问

成员变量:

this: this.成员变量;(访问当前类的)

Super: super.成员变量;(访问父类的)

成员方法:

this: this.xx();

Super: super.xx();

构造方法:

this: this();(访问当前类的无参构造)//切记中间没有点

This: this(“”);(访问当前类的有参构造)//切记中间没有点

super: super();(访问父类的无参构造)//切记中间没有点

super: super(“”);(访问当前类的有参构造)//切记中间没有点友情提示

在继承父类中的构造方法时,系统会默认优先继承父类中的无参构造。

如果父类中没有无参构造时,系统就会报错,有三种解决方法:

1)可以在父类中写出一个无参构造,用以调用

2)通过super关键字在子类中的无参构造和有参构造中就行访问父类的有参构造。例如:

class Fu{

public Fu(String name,int age) {
System.out.println("父类中的有参构造");
}
}
class Zi extends Fu{
public Zi() {
super   ("张三",23);
System.out.println("子类中的无参构造");
}
public Zi(String name,int age) {
super  ("李四",24);
System.out.println("子类中的有参构造");
}
}

在主函数中通过创建子类的类对象,调用子类中构造方法,就可以访问父类中的构造方法了。

3)在子类的有参方法中用this();访问子类的无参构造,然后在子类的无参构造中通过super();去调用父类的构造方法,就可以在主函数中访问了。

成员方法也是一样通过thissuper关键字去访问

继承的好处:1)提高了代码的复用性,解决了代码的臃肿繁琐的问题

2)它是多态的前提(多态的前提必须有继承的关系,多态在接下来会讲到)

关键字:final

final表示最终,终态的意思

1)它可以去修饰类,但是修饰之后就不能被继承

2)它也可以去修饰成员方法,但是修饰之后就不能被重写

3)当它修饰一个变值后,这个变值就变成了常量,不能在进行更改。

多态

多态:在同一时刻,体现出的不同状态。

多态的前提:

1)必须有继承关系

2)必须有方法重写

3)必须有父类的引用指向子类对象

向上转型的格式:父类 父类对象名=new 子类();

多态中的成员访问特点:

1)成员变量:编译看左,运行看右

2)成员方法:编译看左,运行看左

3)构造方法:无论父类子类,都是对对象进行初始化

4)静态成员方法:编译看左,运行看左(静态算不上方法重写)

例如:

package com.test;
class father1{
int a=23;
public void show() {
System.out.println("就这样");
}
public static void asd(){
System.out.println("父类中的静态成员方法");
}
}
class son1 extends father1{
int a=34;
public void method() {
System.out.println("那就这样吧");
}
public void show(){
System.out.println("这是子类的无参构造");
}
public static void asd() {
System.out.println("子类中的静态成员方法");
}
}
public class Dome03 {
 
public static void main(String[] args) {
father1 f=new son1(); //向上转型
System.out.println(f.a);
f.show();
}

}

多态的好处:

可以提供代码的复用性:有继承保证

可以提供代码的扩展性:由多态保证

多态的弊端:

通过父类的引用去调用子类中的特有方法时,是错误的

当用户就想调用子类的特用方法时,应该怎么做?这时向下转型(就是将父类的引用强制转换子类的引用)就出现了

但是向下转型的前提必须有向上转型

格式:子类 子类对象名=(子类)父类对象名;

例如:

package com.test;
class mom{
public void girl() {
System.out.println("他是妈妈");
}
}
class sun extends mom{
public void girl() {
System.out.println("我是儿子");
}
public void play() {
System.out.println("我爱玩游戏");
}
}
public class Dome05 {
 
public static void main(String[] args) {
mom m=new sun();
sun s=(sun) m; //向下转型
s.play();
s.girl();
}
}

如上例所示,向下转型后就可以去访问子类中的特有方法了

友情提示:

当向下转型使用不当时,就会出现一个运行时期异常。

 

猜你喜欢

转载自blog.csdn.net/j_better/article/details/80016923
今日推荐