10.13动手动脑

发布时间 2023-10-13 21:40:20作者: 赵千万
class Grandparent {
public Grandparent() {

System.out.println("GrandParent Created.");

}
public Grandparent(String string) {

System.out.println("GrandParent Created.String:" + string);
}
}


class Parent extends Grandparent {
public Parent() {
super("Hello.Grandparent.");
System.out.println("Parent Created");

}
}


class Child extends Parent {
public Child() {

System.out.println("Child Created");

}

}

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

Child c = new Child();

}
}
 
 
继承时,会先执行父类的构造函数,若子类中没有调用父类的有参构造函数,则会执行父类的无参构造,否则只执行父类的有参构造函数。

 

 

 

子类的构造方法在运行之前通常需要调用父类的构造方法,因为这是确保继承体系中的正确初始化和一致性的关键一步。这是基于以下几个原因:

  1. 初始化继承链:在继承关系中,子类继承了父类的属性和方法。父类可能会有一些关键的初始化操作,这些操作需要在子类的构造方法运行之前执行。通过调用父类的构造方法,确保了整个继承链中的对象都能够正确初始化。

  2. 父类资源分配:父类的构造方法可能会分配一些资源,如内存、文件句柄、数据库连接等。这些资源需要在子类构造方法之前分配和初始化,以避免资源泄漏或冲突。

  3. 父类初始化属性:父类可能会在构造方法中初始化一些属性,这些属性可能对子类的构造方法和行为产生影响。子类需要确保在其构造方法运行之前,这些属性已经正确初始化。

虽然子类的构造方法通常需要调用父类的构造方法,但父类的构造方法不能调用子类的构造方法。这是因为子类是基于父类构造的,子类构造方法中可能包含了父类构造方法没有的初始化步骤。如果反过来调用子类构造方法,会导致初始化的顺序混乱,可能会导致不可预测的行为和错误。

总之,调用父类构造方法是确保继承体系正确初始化的关键部分,而反过来调用子类构造方法通常不合适且不安全。在面向对象编程中,遵循调用父类构造方法的惯例是一种良好的实践,以确保继承体系的可靠性和一致性。

 

构造函数的主要作用是在创建对象时执行必要的初始化操作。构造函数通常是一个特殊的方法或函数,用于为类或对象分配内存空间并设置初始值。它具体的作用包括:

  1. 分配内存空间:构造函数负责为对象分配内存空间,确保对象具有足够的存储来存储其属性和数据。

  2. 初始化属性:构造函数用于设置对象的属性或成员变量的初始值。这有助于确保对象在创建后处于一个已知的状态,以避免潜在的错误或不一致性。

  3. 执行必要的初始化操作:构造函数可以执行与对象相关的任何其他初始化操作,例如打开文件、建立数据库连接、初始化数据结构等。

  4. 提供灵活性:构造函数通常具有参数,允许在创建对象时传递不同的参数值,从而在不同情况下创建具有不同属性值的对象。

构造函数通常在对象创建时由编程语言的实例化机制自动调用,以确保对象的合理初始化。不同编程语言可能有不同的构造函数语法和约定,但它们都具有相似的目标:初始化新创建的对象。

 

 

final声明的方法不能覆写,变量不能更改,类不能被继承

 

 

示例中定义了一个类A,它没有任何成员: class A { } 示例直接输出这个类所创建的对象 public static void main(String[] args) { System.out.println(new A()); }

在这个示例中,定义了一个类A,它没有任何成员或属性。然后,在main方法中,直接创建了一个类A的对象并使用System.out.println方法将其输出。由于类A没有定义任何属性或方法,输出的结果将会是该对象的默认字符串表示形式。

在Java中,如果类没有显式定义toString方法,那么将使用从java.lang.Object类继承的默认toString方法。默认的toString方法将返回一个字符串,格式为类的名称,后跟@符号和对象的哈希码的十六进制表示。例如,输出可能类似于以下内容:

A@15db9742

其中"A"是类的名称,"@15db9742"是对象的哈希码的十六进制表示。

请注意,虽然示例中没有定义任何成员的类A,但每个Java类都继承了一些方法和属性,包括toString方法,因此即使没有显式定义,也可以使用默认的toString方法。如果你想要自定义对象的字符串表示形式,你可以重写toString方法,以便返回你希望的格式。

 

 




class Parent {
public Parent() {
System.out.println("Parent Created");

}
public void eat()
{
System.out.println("喝");
}
}


class Child extends Parent {
public Child() {


System.out.println("Child Created");
}
public void eat()
{
System.out.println("睡");
}

}

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


Child c = new Child();
c.eat();

}
}

(1)覆盖方法的允许访问范围不能小于原方法。
(2)覆盖方法所抛出的异常不能比原方法更多。
(3)声明为final方法不允许覆盖。
例如,Object的getClass()方法不能覆盖。
(4)不能覆盖静态方法。

 

 

public class Main
{
public static void main(String[] args)
{
//声明hello时使用Object类,则hello的编译类型是Object,Object是所有类的父类
//但hello变量的实际类型是String
Object hello = "Hello";
//String是Object类的子类,所以返回true。
System.out.println("字符串是否是Object类的实例:" + (hello instanceof Object));
//返回true。
System.out.println("字符串是否是String类的实例:" + (hello instanceof String));
//返回false。
System.out.println("字符串是否是Math类的实例:" + (hello instanceof Math));
//String实现了Comparable接口,所以返回true。
System.out.println("字符串是否是Comparable接口的实例:" + (hello instanceof Comparable));
String a = "Hello";
//String类既不是Math类,也不是Math类的父类,所以下面代码编译无法通过
//System.out.println("字符串是否是Math类的实例:" + (a instanceof Math));
}
}
 
现在有三个类: class Mammal{} class Dog extends Mammal {} class Cat extends Mammal{} 针对每个类定义三个变量并进行初始化 Mammal m=null ; Dog d=new Dog(); Cat c=new Cat(); 下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么? m=d; d=m; d=(Dog)m; d=c; c=(Cat)m;
  1. m=d;:这个语句不会引起编译错误,因为DogMammal的子类,所以将一个Dog对象分配给Mammal类型的变量是合法的。这是多态性的一个示例。

  2. d=m;:这个语句将引起编译错误。虽然DogMammal的子类,但将一个Mammal类型的变量分配给Dog类型的变量需要进行强制类型转换。因为Java编译器不能确定m引用的对象实际上是Dog,所以需要显式的类型转换。

  3. d=(Dog)m;:这个语句不会引起编译错误,因为它包含了显式的类型转换,将Mammal类型的变量m强制转换为Dog类型。

  4. d=c;:这个语句将引起编译错误,因为CatDog是不同的子类,它们之间没有直接的继承关系。

  5. c=(Cat)m;:这个语句将在运行时引起ClassCastException异常。即使在编译时没有错误,但因为m引用的对象是一个Dog,试图将其强制转换为Cat是不合法的,因为DogCat之间没有继承关系,所以这会导致运行时异常。

 

 

有abstract修饰的类称为“抽象类”,它只定义了什么方法应该存在,不能创建对象,必须派生出一个子类,并在子类中实现其未实现的方法之后,才能使用new关键字创建对象。
在方法前加上abstract就形成抽象方法,只有方法声明,没有实现代码

abstract class Person
{
public abstract String getDescription();
}
一个抽象类中可以包含非抽象方法和成员变量。包含抽象方法的类一定是抽象类,但抽象类中的方法不一定是抽象方法

直接定义了一个抽象方法
继承了一个抽象父类,但没有完全实现父类包含的抽象方法
实现了一个接口,但没有完全实现此接口所包容的抽象方法。

 

 

定义一个接口,采用关键字interface,实现一个接口,采用关键字implements
接口的成员函数自动成为public的,数据成员自动成为
static和final的。
如果接口不声明为public的,则自动变为package。
一个类可以同时实现多个接口。