《JAVA编程思想》第五、六、七、八章总结

第五章

1.构造器是什么?

构造函数(构造器)是一种特殊的函数。其主要功能是用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。构造函数与类名相同,没有返回值,但不能声明void,访问权限可以为任意,但是一般情况下使用public方法权限,构造方法中的参数可以根据需要自行定义,可重载多个不同的构造函数。在JAVA语言中,构造函数与C++语言中的构造函数相同,JAVA语言中普遍称之为构造方法。

2.重载和重写有什么区别?

重载(overloading):在同一个类中同名函数,具有不同参数个数和类型(返回值不参与),是一个类中多态性的体现。是由静态类型确定,在类加载的时候就已经确定了,属于静态绑定。(当子类和父类存在同一个方法时,子类重写父类方法时,程序在运行时调用的方法时,是调用父类(接口)的方法呢?还是调用子类的方法呢?我们将确定这种调用何种方法的操作称之为绑定。)

重写(overriding):子类中含有与父类中相同的名字、返回值类型和参数表的方法,则是重写。是在继承中体现多态性,属于动态绑定。

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态,后者实现的是运行时的多态。

3.this 和super关键字

this:

this 是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针

this 的用法在 Java 中大体可以分为3种:

1.普通的直接引用

这种就不用讲了,this 相当于是指向当前对象本身。

2.形参与成员名字重名,用 this 来区分:

class Person {
    private int age = 10;
    public Person(){
    System.out.println("初始化年龄:"+age);
}
    public int GetAge(int age){
        this.age = age;
        return this.age;
    }
}
 
public class test1 {
    public static void main(String[] args) {
        Person Harry = new Person();
        System.out.println("Harry's age is "+Harry.GetAge(12));
    }
}

可以看到,这里 age 是 GetAge 成员方法的形参,this.age 是 Person 类的成员变量。

super

super 可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类

super 也有三种用法:

1.普通的直接引用

与 this 类似,super 相当于是指向当前对象的父类,这样就可以用 super.xxx 来引用父类的成员。

2.子类中的成员变量或方法与父类中的成员变量或方法同名

class Country {
    String name;
    void value() {
       name = "China";
    }
}
  
class City extends Country {
    String name;
    void value() {
    name = "Shanghai";
    super.value();      //调用父类的方法
    System.out.println(name);
    System.out.println(super.name);
    }
  
    public static void main(String[] args) {
       City c=new City();
       c.value();
       }
}

可以看到,这里既调用了父类的方法,也调用了父类的变量。若不调用父类方法 value(),只调用父类变量 name 的话,则父类 name 值为默认值 null。

3.引用构造函数

  • super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。
  • this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。
class Person { 
    public static void prt(String s) { 
       System.out.println(s); 
    } 
   
    Person() { 
       prt("父类·无参数构造方法: "+"A Person."); 
    }//构造方法(1) 
    
    Person(String name) { 
       prt("父类·含一个参数的构造方法: "+"A person's name is " + name); 
    }//构造方法(2) 
} 
    
public class Chinese extends Person { 
    Chinese() { 
       super(); // 调用父类构造方法(1) 
       prt("子类·调用父类"无参数构造方法": "+"A chinese coder."); 
    } 
    
    Chinese(String name) { 
       super(name);// 调用父类具有相同形参的构造方法(2) 
       prt("子类·调用父类"含一个参数的构造方法": "+"his name is " + name); 
    } 
    
    Chinese(String name, int age) { 
       this(name);// 调用具有相同形参的构造方法(3) 
       prt("子类:调用子类具有相同形参的构造方法:his age is " + age); 
    } 
    
    public static void main(String[] args) { 
       Chinese cn = new Chinese(); 
       cn = new Chinese("codersai"); 
       cn = new Chinese("codersai", 18); 
    } 
}

从本例可以看到,可以用 super 和 this 分别调用父类的构造方法和本类中其他形式的构造方法。

例子中 Chinese 类第三种构造方法调用的是本类中第二种构造方法,而第二种构造方法是调用父类的,因此也要先调用父类的构造方法,再调用本类中第二种,最后是重写第三种构造方法。

从本质上讲,this 是一个指向本对象的指针, 然而 super 是一个 Java 关键字

 

4.初始化顺序

正常类的加载顺序:静态变量/静态代码块 -> main方法 -> 非静态变量/代码块 -> 构造方法

如果是继承关系的子类初始化顺序:

父类–静态变量/父类–静态初始化块
子类–静态变量/子类–静态初始化块
父类–变量/父类–初始化块
父类–构造器
子类–变量/子类–初始化块
子类–构造器

第六章

1.JAVA中的权限关键字

第七章

1.组合和继承的区别,如何选择使用?

组合:其实一开始就接触了但不知道这就叫组合,本质就是类的复用。我们创建一个类A,之后再创建一个新的类B,在B类中通过创建A类对象,来调用A类方法。

下面通过具体的例子来展示如何使用:

public class People {
    private String name;
    private int age;
    
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
    public int getAge(){
        return this.age;
    }
    public void setAge(int age){
        this.age = age;
    }
}
class Student {
    People people = new People();
}

这里的Student类就是运用了组合。

继承:这个很熟悉了,直接贴用法

public class Student extends People{
    //doSomething
}

总结一下:

组合:只需在新的类中产生现有类的对象。新的类是由现有类的对象所组成的。
继承:按照现有类的类型来创建新类,无需改变现有类的形式,并且在其中添加新的代码。

区别:组合是显示地允许在新类中放置子对象,而继承是隐性的这样做。

 

选择使用问题:

从语言的逻辑上看,继承(extend)更应该用于包含关系(sth is a sth_baby),而组合可以是并列或者说共有的关系(sth has a sth_baby)。

2.final关键字总结

final关键字可以修饰变量、方法和类。

1.用来修饰数据:包括成员变量和局部变量,该变量只能被赋值一次且它的值无法被改变。对于成员变量来讲,修饰的类变量,必须在声明时初始化;修饰的实例变量,必须在声明时或者构造方法中对它赋值。对于基本数据类型,final会使得数值不变;而对于引用类型,final会使得引用指向的对象不变。
2.用来修饰方法:第一个原因表示该方法无法被重写,防止继承的子类去修改该方法;第二个原因是效率。

tips:类中所有private方法都隐式地使用了final关键字。

3修饰类:表示该类无法被继承

第八章

1.为什么要有多态的存在?

个人简单的理解:父类型的引用指向子类型的对象。使用多态有两个好处:

1. 应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的可复用性。 
2. 派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。 

多态可以用在方法的参数中和方法的返回类型中。

举个例子:


package stduy;
 
abstract  class Animal{
	abstract void eat();
}
 
class Dog extends Animal{
	public void eat() {
		System.out.println("啃骨头!");
	}
	public void LookHome() {
		System.out.println("看家!");
	}
}
 
class Cat extends Animal{
	public void eat() {
		System.out.println("吃鱼!");
	}
	public void catchMouse() {
		System.out.println("抓老鼠!");
	}
}
 
public class Main{
	
	public static void main(String[] args) {
			Dog dog = new Dog();
			
			dog.eat();
			dog.LookHome();
			
			Cat cat = new Cat();
			cat.eat();
			cat.catchMouse();
	}
	
}

这里主方法分别去调用各个子类的eat方法就很麻烦,我们这里就可以使用多态。


public class Main{
	
	public static void main(String[] args) {
		
			Dog dog = new Dog();		
			Cat cat = new Cat();
			
			method(dog);
			method(cat);
	}
	public static void method(Animal a) {
		a.eat();
	}

}

 

2.向上转型和向下转型是什么,为什么要用它们?

向上转型和向下转型都非常抽象,需要举例说明:


class Father {
	String name = "爸爸";
	public void sleep() {//睡觉方法
		System.out.println(name + "睡觉");
	}
}
/**
 * 子类继承父类
 */
class Son extends Father {
	String name = "儿子";
	public void p() {//调皮方法
		System.out.println(name + "调皮");
	}

我们先建立一堆父子类。


public class UpAndDown {
	public static void main(String[] args) {
		// 向上转型:将父类引用指向子类对象
		Father f = new Son();
		f.sleep();//输出“爸爸睡觉”
      
        //如果f.p();编译出错,不可执行。因为p()不是Father的方法。
	}
}

很明显,上面的就是向上转型,将子类转型成父类,此时子类特有的p()方法就无法调用,但这样做,方便我统一控制多个子类。


public class UpAndDown {
	public static void main(String[] args) {
		// 向下转型
		Father f = new Son();
		((Son)f).P();//输出“儿子调皮”
	}
}

上面就是向下转型,将向上转型的子类再向下转型,这样原本子类特有的方法p()就可以使用了。


public class UpAndDown {
	public static void main(String[] args) {
		// 直接向下转型
		Father f = new Father();
        f.sleep();//输出“爸爸睡觉”
		((Son)f).P();//报错!!!!!!!!!!
	}

}

但如果我写成以上的向下转型就不行,因为他在创建对象时创建的就是父类对象,根本就不包含子类特有的方法,无法下转。所以下转的前提是你本来就有,只不过由于向上转型失去了,然后通过下转再次恢复。

为什么要用它们

向上转型:这个好理解java的继承,多态. 利于程序扩展。这种设计方式,会让你写出更易维护,简洁的代码。

但向下转型就有点难以理解了,为什么我要先上转再下转,多这一步呢,我子类引用指向新建的一个子类对象不就好了?

这篇博客写的很详细:

https://blog.csdn.net/xyh269/article/details/52231944

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章