黑马程序员——java中构造函数、继承、多态、接口总结

来源:互联网 发布:怎么加入淘宝充值平台 编辑:程序博客网 时间:2024/05/21 07:11
------Java培训、Android培训、期待与您交流! -------

一、构造函数

     1、概念和作用
          构造函数是构建创造对象时调用的函数。构造函数可以给对象进行初始化。在主函数中创建对象时必须要通过构造函数进行初始化。一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参数构造函数。另外也可以在类中定义了指定的构造函数,此时创建对象时调用的是自定义的构造函数。
     2、构造函数和一般函数的区别
          构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化。对象创建时,会调用只调用一次。没返回值
          一般函数:对象创建后,需要函数功能时才调用。 对象创建后,可以被调用多次。有返回值
     3、构造函数的重载
         在 Java 里,不仅一般函数可以重载,构造函数也可以重载。只要构造函数的参数个数不同,或是类型不同,便可定义多个名称相同的构造函数。
//构造函数重载class Person {private String name;private int age;public Person() {//空参数构造函数}Person(String n, int a) {//带有两个参数的构造函数name = n;age = a;}public String talk() {return "我是: " + name + ",今年: " + age + "岁 ";}}public class Construct {public static void main(String[] args) {Person p = new Person();//调用空参数构造函数System.out.println(p.talk());//打印姓名和年龄Person p1 = new Person("小明",20);//调用有参数构造函数并传入参数System.out.println(p1.talk());//打印姓名和年龄}}

输出结果为:
我是: null,今年: 0岁      
我是: 小明,今年: 20岁
由结果可以看出:构造函数中String类型默认初始化值为null,int类型默认初始化值为0。

    4、this关键字

class Person {String name;int age;public Person() {System.out.println("1. public Person()");}public Person(String name, int age) {this();// 调用本类中无参构造方法,即Person(){},必须定义在构造函数的第一行this.name = name;//this表示当前对象this.age = age;//this表示当前对象System.out.println("2. public Person(String name,int age)");}}public class TestThis {public static void main(String[] args) {new Person("小明", 20);}}

输出结果为:

1. public Person()
2. public Person(String name,int age)

          由此可见,this关键字可以表示当前对象,也可以在构造函数中调用另一个构造函数。


     5、static关键字

class Person {String name;private static String city = "北京";// 静态变量被所有对象共享int age;public Person() {System.out.println("1.public Person()");}// 此段代码会首先被执行——静态代码块static {System.out.println("2.Person 类的静态代码块被调用! ");}public Person(String name, int age) {this.name = name;this.age = age;}public String talk() {return "我是:" + this.name + ",今年:" + this.age + "岁,来自:" + city;}// 静态方法定义的内容可以用于非静态和静态方法中使用// 静态方法中使用非静态方法中的内容时会报错public static void setCity(String c) {city = c;}}public class TestStatic {// 运行本程序时,静态代码块会被自动执行static {System.out.println("3.TestStatic 类的静态代码块被调用! ");}public static void main(String[] args) {System.out.println("4.程序开始执行! ");// 产生两个实例化对象Person p1 = new Person("小明", 25);Person p2 = new Person("小红", 23);System.out.println("修改之前信息: " + p1.talk());System.out.println("修改之前信息: " + p2.talk());System.out.println(" **************修改之后信息**************");// 修改后的信息Person.setCity("上海");// 静态方法可以用类名直接调用System.out.println("修改之后信息: " + p1.talk());System.out.println("修改之后信息: " + p2.talk());}}

输出结果为:

3.TestStatic 类的静态代码块被调用! 
4.程序开始执行! 
2.Person 类的静态代码块被调用! 
修改之前信息: 我是:小明,今年:25岁,来自:北京
修改之前信息: 我是:小红,今年:23岁,来自:北京
 **************修改之后信息**************
修改之后信息: 我是:小明,今年:25岁,来自:上海
修改之后信息: 我是:小红,今年:23岁,来自:上海

         由以上程序可以得出,static关键字可以用于修饰变量、方法和代码块。静态变量被所有对象共享。静态方法中不可以使用非静态内容,当函数功能没有访问到对象的特有内容时就可以定义为静态。静态代码块用于给类进行初始化,会先执行。


     6、内部类

         分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容。这时就是还有的事物定义成内部类来描述。内部类可以直接访问外部类中的成员。外部类要访问内部类,必须建立内部类的对象。

//内部类总结class Outer {int score = 95;// 外部类可以访问内部类中的成员,内部类持有了外部类的引用: 外部类名.thisvoid inst() {Inner in = new Inner();in.display();}// 内部类在局部位置上只能访问局部中被final修饰的局部变量。void inst1(final int s) {final int temp = 20;class Inner1 {void show() {System.out.println("成绩1:score=" + (score + s + temp));}}Inner1 in = new Inner1();in.show();}// static class Inner{}// 用 static 声明的内部类则变成外部类,但是用 static 声明的内部类不能访问非 static 的外部类属性public class Inner {void display() {// 在内部类中声明一name属性// String name = "小明";System.out.println("成绩: score = " + score);// Outer.this.score}// static void function(){//如果内部类中定义了静态成员,该内部类也必须是静态的。// System.out.println("function run ...."+score); }}// 在此调用内部类的name属性,会产生错误,外部类不能访问内部类中的属性 public void print(){// System.out.println("姓名:"+name); }}public class InnerClassDemo {public static void main(String[] args) {Outer out = new Outer();out.inst();// 直接访问外部类中的内部类中的成员。Outer.Inner in = new Outer().new Inner();in.display();// 如果内部类是静态的。 相当于一个外部类// Outer.Inner in = new Outer.Inner();// in.display();// 如果内部类是静态的,成员是静态的。// Outer.Inner.function();out.inst1(5);}}

输出结果为:

成绩: score = 95
成绩: score = 95
成绩1:score=120          


二、继  承

     1、继承相关概念

         java中继承用到extends关键字。当类与类之间存在着所属关系(is-a)时,就定义继承。被继承的类成为父类或超类,继承得到的新类成为子类或派生类。父类是子类不断向上抽取出来的。如:class Students(子类) extends Person(父类)。子类会继承父类的所有属性和方法。

         java中不允许多继承,即一个子类不允许有多个父类。但是允许多层继承,即C继承B,B继承A,就出现了继承体系。

    2、子类继承父类的特性

        2.1  子类实例化

一个对象实例化过程:

Person p = new Person();

  • JVM会读取指定的路径下的Person.class文件,并加载进内存,并会先加载Person的父类(如果有直接的父类的情况下);
  • 在堆内存中的开辟空间,分配地址;
  • 并在对象空间中,对对象中的属性进行默认初始化;
  • 调用对应的构造函数进行初始化;
  • 在构造函数中,第一行会先到调用父类中构造函数进行初始化;
  • 父类初始化完毕后,在对子类的属性进行显示初始化;
  • 在进行子类构造函数的特定初始化;
  • 初始化完毕后,将地址值赋值给引用变量。

        2.2  super关键字:用于子类中,调用父类中的构造方法,此时只能放在子类程序的第一行。另外可以通过(super.父类中的属性或方法)来调用父类的内容。但是子类不能访问父类中的私有内容。super关键字与this关键字调用构造函数的操作是不能同时出现的。

        2.3  覆盖

        当子父类中出现成员函数一模一样的情况,会运行子类的函数。这种现象,称为覆盖操作。当对一个类进行子类的扩展时,子类需要保留父类的功能声明,但是要定义子类中该功能的特有内容时,就使用覆盖操作完成。这时函数在子父类中的的两个特性:

  • 重载。同一个类中。overload
  • 覆盖。子类中。覆盖也称为重写,覆写。override
当子类覆盖父类中的内容时,需要注意的是:子类方法覆盖父类方法时,子类权限必须要大于等于父类的权限,并且静态内容只能覆盖静态内容,或被静态内容覆盖。


//继承总结class Person {String name;int age;// 父类中构造函数public Person() {System.out.println("1.public Person(){}");}// 父类中构造函数public Person(String name, int age) {// this关键字代表当前对象this.name = name;this.age = age;}// 父类中的方法public String talk() {// this调用本类中的内容return "我是: " + this.name + ",今年: " + this.age + "岁 ";}}// Student类继承于Person类class Student extends Person {String school;// 子类中的构造函数public Student() {// super();隐含super调用父类中的空参数构造函数System.out.println("2.public Student(){}");}public Student(String name, int age, String school) {// 分别为属性赋值this.name = name;this.age = age;this.school = school;}// 此处复写 Person 类中的 talk()方法,并用super调用父类中的talk方法public String talk() {return super.talk() + ",我在" + this.school + "上学";}}class ExtendsDemo2 {public static void main(String[] args) {Student s = new Student();Student ss = new Student("小明", 23, "北京");// 此时调用的是子类中的 talk()方法System.out.println(ss.talk());}}

输出结果为:

1.public Person(){}
2.public Student(){}
1.public Person(){}
我是: 小明,今年: 23岁 ,我在北京上学


三、抽象类

     

    抽象类定义规则

  •  抽象类和抽象方法都必须用 abstract 关键字来修饰。
  •  抽象类不能被实例化,也就是不能用 new 关键字去产生对象。
  •  抽象方法只需声明,而不需实现。
  •  含有抽象方法的类必须被声明为抽象类,抽象类的子类必须复写所有的抽象方法后才能被实例化,否则这个子类还是个抽象类。

//抽象类abstract class Person {String name;int age;String occupation;//抽象类中定义构造函数public Person(String name, int age, String occupation) {this.name = name;this.age = age;this.occupation = occupation;}// 定义抽象方法 talk()public abstract String talk();}// Student 类继承自 Person 类class Student extends Person {public Student(String name, int age, String occupation) {//调用抽象类中的构造函数super(name, age, occupation);}//覆盖 talk()方法public String talk() {return "学生的姓名: " + this.name + ",年龄: " + this.age + ",职业:"+ this.occupation + "! ";}}// Worker 类继承自 Person 类class Worker extends Person {public Worker(String name, int age, String occupation) {//调用抽象类中的构造函数super(name, age, occupation);}// 覆盖 talk()方法public String talk() {return "工人的姓名: " + this.name + ",年龄: " + this.age + ",职业:"+ this.occupation + "! ";}}class AbstractDemo {public static void main(String[] args) {Student s = new Student("小明", 20, "学生");//创建Student对象Worker w = new Worker("小强", 28, "工人");//创建Worker对象System.out.println(s.talk());//调用的方法System.out.println(w.talk());//调用的方法}}


输出结果为:

学生的姓名: 小明,年龄: 20,职业:学生! 工人的姓名: 小强,年龄: 28,职业:工人! 

四、接  口

    当一个抽象类中的方法都是抽象的时候,这时可以将该抽象类用另一种形式定义和表示,就是 接口( interface)。接口里的数据成员必须初始化,且数据成员均为常量。接口里的方法必须全部声明为 abstract,也就是说,接口不能像抽象类一样有一般方法,而必须全部是“抽象方法”。对于接口当中的成员都有固定的修饰符。全局常量: public  static final ;抽象方法。public abstract。接口是java实现多继承的一种机制,它可以通过多实现来达到多继承的效果。

//定义接口interface A {int i = 10;//public static final int i = 10;public void sayI();//public abstract void sayI();}interface E {int x = 40;public void sayE();}// B 同时继承了 A、 E 两个接口interface B extends A, E {int j = 20;public void sayJ();}// C 继承实现 B 接口,也就意味着要实现 A、 B、 E 三个接口的抽象方法class C implements B {public void sayI() {System.out.println("i = " + i);}public void sayJ() {System.out.println("j = " + j);}public void sayE() {System.out.println("e = " + x);}}class InterfaceDemo {public static void main(String[] args) {C c = new C();c.sayI();c.sayJ();c.sayE();}}

输出结果为:

i = 10
j = 20
e = 40


五、多  态

     一个对象对应着不同类型即为多态。如动物对象里有猫和狗两种形态。在java中多态体现在父类或接口的引用指向其子类对象。多态的存在提高了代码的扩展性,但是使用多态后前期定义的内容不能使用(调用)后期子类的特有内容。多态涉及两个转型:向上转型和向下转型。向上转型会自动完成,向下转型需要进行强制类型转换。


//定义多态abstract class Person {abstract void talk();}//American类继承Person类class American extends Person {void talk() {System.out.println("说英语");}void playbasketball() {System.out.println("打篮球");}}//Japanese类继承Person类class Japanese extends Person {void talk() {System.out.println("说日语");}void tea() {System.out.println("喝茶");}}class DuoTaiDemo {public static void main(String[] args) {Person a = new American(); // 向上转型,隐藏子类的特有内容。。American c = (American) a;// 向下转型的目的是为了使用子类中的特有方法。c.talk();c.playbasketball();// 对于转型,自始自终都是子类对象在做着类型的变化。// Person a1 = new Japanese();// Japanese c1 = (Japanese)a1;//ClassCastExceptionmethod(new Japanese());}public static void method(Person p) {p.talk();// instanceof:用于判断对象的具体类型。只能用于引用数据类型判断,通常在向下转型前用于健壮性的判断。if (p instanceof American) {American a = (American) p;a.playbasketball();} else if (p instanceof Japanese) {Japanese j = (Japanese) p;j.tea();} else {}}}

输出结果为:

说英语
打篮球
说日语
喝茶





------Java培训、Android培训、期待与您交流! -------
0 0
原创粉丝点击