黑马程序员_面向对象下-1

 ------- android培训、java培训、期待与您交流! ----------

面向对象下-1

1.代码块的概述和分类(面试的时候会问,开发不用或者很少用)

* A:代码块概述

         *在Java中,使用{}括起来的代码被称为代码块。

* B:代码块分类

         *根据其位置和声明的不同,可以分为局部代码块(和方法有关,写在方法中),构造代码块,静态代码块,同步代码块(多线程讲解)。

* C:常见代码块的应用

         *a:局部代码块

                   *在方法中出现;限定变量生命周期,及早释放,提高内存利用率

  {  }    * b:构造代码块 (初始化块) //构造代码块:每创建一次对象就会执行一次,优先于构造函数执行

                   *在类中方法外出现;多个构造方法方法中相同的代码存放到构造代码块中,每次调用构造都执行,并且在构造方法前执行

         *c:静态代码块 static{  }

             * 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次

             * 一般用于加载驱动

            //静态代码块是优先于主方法执行,随着类加载而加载,且只执行一次


2.代码块练习题:

* A:看程序写结果

                   classStudent {

                            static{

                                     System.out.println("Student静态代码块");

                            }

                           

                            {

                                     System.out.println("Student构造代码块");

                            }

                           

                            publicStudent() {

                                     System.out.println("Student构造方法");

                            }

                   }

                   classDemo2_Student {

                            static{

                                     System.out.println("Demo2_Student静态代码块");

                            }

                           

                            publicstatic void main(String[] args) {

                                     System.out.println("我是main方法");

                                     Students1 = new Student();

                                     Students2 = new Student();

                            }

                   }

      输出结果: Demo2_Student静态代码块

                   我是main方法

                   Student静态代码块

                   Student构造代码块

                   Student构造方法

                   Student构造代码块

                   Student构造方法


3.继承的好处和弊端

* A:继承的好处

         *a:提高了代码的复用性

         *b:提高了代码的维护性

         *c:让类与类之间产生了关系,是多态的前提

* B:继承的弊端

         *类的耦合性增强了。(他们的紧密性太紧密了,父类增加了一个属性,子类就增加了一个,但有时这个子类并不期望)  

         *开发的原则:高内聚,低耦合。

         *耦合:类与类的关系

         *内聚:就是自己完成某件事情的能力

4.Java中类的继承特点

* A:Java中类的继承特点

         *a:Java只支持单继承,不支持多继承。(一个儿子只能有一个爹)  //多继承有安全隐患

                   *有些语言是支持多继承,格式:extends 类1,类2,...

         *b:Java支持多层继承(继承体系)

* B:Java中类的继承特点

                   *如果想用这个体系的所有功能用最底层的类创建对象

                   *如果想看这个体系的共性功能,看最顶层的类

 

5.继承的注意事项和什么时候使用继承(

* A:继承的注意事项

         *a:子类只能继承父类所有非私有的成员(成员方法和成员变量)

         *b:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法。

         构造方法和类名相同,都是为了给自己本类去创建对象使用的,所以不能继承

         *c:不要为了部分功能而去继承

         *项目经理 姓名 工号 工资 奖金

         *程序员         姓名 工号 工资   //

         //不能项目经理继承程序员或反过来,应当先将共有的抽出来放到员工类中,他们两个都继承员工类

* B:什么时候使用继承

         *继承其实体现的是一种关系:"is a"。

                   Person

                            Student

                            Teacher  //学生和老师是人的一种

                   水果

                            苹果

                            香蕉

                            橘子   //苹果,香蕉, 是水果的一种            

         采用假设法,如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。

 

6.继承中成员变量的关系

* A:案例演示

         *a:不同名的变量

         *b:同名的变量    

         //也是采用就近原则,子类有,就不用父类的了

         //子父类出现同名的变量只是在讲课中举例子有,在开发中是不会出现这种情况的

         //子类继承父类就是为了使用父类的成员,父类如果有子类就没有必要定义了

         //this既可以调用本类的,也可以调用父类的(本类没有的情况下)


7.this和super的区别和应用

* A:this和super都代表什么

         *this:代表当前对象的引用,谁来调用我,我就代表谁 

         *super:代表当前对象父类的引用   (父类)

* B:this和super的使用区别

         *a:调用成员变量

                   *this.成员变量 : 调用本类的成员变量,也可以调用父类的成员变量(本类没有的情况下)

                   *(super.成员变量) : 调用父类的成员变量

         *b:调用构造方法

                   *this(...)  调用本类的构造方法

                   *super(...)       调用父类的构造方法

         *c:调用成员方法

                   *this.成员方法调用本类的成员方法,也可以调用父类的方法

                   *super.成员方法调用父类的成员方法

8.继承中构造方法的关系

* 子类中所有的构造方法默认都会访问父类中空参数的构造方法

* B:为什么呢?

         *因为子类会继承父类中的数据,可能还会使用父类的数据。

         *所以,子类初始化之前,一定要先完成父类数据的初始化。    

         *其实: 每一个构造方法的第一条语句默认都是:super(); Object类最顶层的父类。//不写继承,默认都是继承Object这个类, 每一个构造方法在开始第一句都默认隐藏了super();

 

9.继承中构造方法的注意事项

* A:父类没有无参构造方法,子类怎么办?

         *super解决  //在开头第一句添加super(参数); 访问父类有参构造

         *this解决   //同上, 访问本类

* B:注意事项

         *super(…)或者this(….)必须出现在构造方法的第一条语句上

 

class Demo6_Extends {

         publicstatic void main(String[] args) {

                   Sons1 = new Son();

                   System.out.println(s1.getName()+ "..." + s1.getAge());

                   //输出结果:Father 有参构造,Son 有参构造,Son 空参构造,王五...25

                   System.out.println("--------------------");

                   Sons2 = new Son("张三",23);

                   System.out.println(s2.getName()+ "..." + s2.getAge());

                   //输出结果Father 有参构造,Son 有参构造,张三...23

         }

}

class Father {

         privateString name;                           //姓名

         privateint age;                                     //年龄

 

         publicFather() {                                    //空参构造

                   System.out.println("Father空参构造");

         }

 

         publicFather(String name,int age) {        //有参构造

                   this.name= name;

                   this.age= age;

                   System.out.println("Father有参构造");

         }

 

         //set和get方法

 

class Son extends Father {

         publicSon() {                                                   //空参构造

                   this("王五",25);                                   //调用本类中的构造方法

                   //super("李四",24);                                     //调用父类中的构造方法

                  

                   System.out.println("Son空参构造");

         }

         publicSon(String name,int age) {     //有参构造

                   super(name,age);

                   System.out.println("Son有参构造");

         }

}

 

10.继承中的练习题:

         看程序写结果1

                   classFu{

                            publicint num = 10;

                            publicFu(){

                                     System.out.println("fu");

                            }

                   }

                   classZi extends Fu{

                            publicint num = 20;

                            publicZi(){

                                     System.out.println("zi");

                            }

                            publicvoid show(){

                                     intnum = 30;

                                     System.out.println(num);

                                     System.out.println(this.num);  //调用本类的成员变量,不是局部变量

                                     System.out.println(super.num);  //调用父类的成员变量

                            }

                   }

                   classTest1_Extends {

                            publicstatic void main(String[] args) {

                                     Ziz = new Zi();

                                     z.show();

                            }

                   }

 

                            输出结果:fu,zi,30,20,10

 

                   看程序写结果2

                   classFu {

                            static{

                                     System.out.println("静态代码块Fu");

                            }

        

                            {

                                     System.out.println("构造代码块Fu");

                            }

                            publicFu() {

                                     System.out.println("构造方法Fu");

                            }

                   }

                   classZi extends Fu {

                            static{

                                     System.out.println("静态代码块Zi");

                            }

        

                            {

                                     System.out.println("构造代码块Zi");

                            }

        

                            publicZi() {

                                     System.out.println("构造方法Zi");

                            }

                   }

*Zi z = new Zi(); 请执行结果:

 1,jvm调用了main方法,main进栈

  2,遇到Zi z = new Zi();会先将Fu.class和Zi.class分别加载进内存,再创建对象,当Fu.class加载进内存父类的静态代码块会随着Fu.class一起加载,当Zi.class加载进内存,子类的静态代码块会随着Zi.class一起加载,第一个输出,静态代码块Fu,第二个输出静态代码块Zi

  3,走Zi类的构造方法,因为java中是分层初始化的,先初始化父类,再初始化子类,所以先走的父类构造,但是在执行父类构造时,发现父类有构造代码块,构造代码块是优先于构造方法执行的所以第三个输出构造代码块Fu,第四个输出构造方法Fu

 4,Fu类初始化结束,子类初始化,第五个输出的是构造代码块Zi,构造方法Zi

 

11.继承中成员方法关系(掌握)

  * a:不同名的方法       //直接调用相关方法即可!!!

  *b:同名的方法     //重写了父类方法,这时就近原则,如果还是想调用父类的同名方法可以super.方法名

 

12.方法重写概述及其应用

* A:什么是方法重写

         *重写:子父类出现了一模一样的方法(注意:返回值类型可以是子父类,这个我们学完面向对象讲???)

class Demo4_Override {

         publicstatic void main(String[] args) {

                  

         }

}

 

class Person {

         publicvoid print() {

                   System.out.println("Person");

         }

}

 

class Student extends Person {

         publicvoid print() {

                   System.out.println("Student");

         }

}

 

class Father {

         publicPerson method() {

                   returnnew Person();

         }

}

 

class Son extends Father {

         publicStudent method() {

                   returnnew Student();

         }

}

* B:方法重写的应用:

         *当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。这样,即沿袭了父类的功能,又定义了子类特有的内容。(继承父类中子类觉得好的功能,不好的子类重写)


13.方法重写的注意事项

* A:方法重写注意事项

         *a:父类中私有方法不能被重写

                   *因为父类私有方法子类根本就无法继承

         *b:子类重写父类方法时,访问权限不能更低

                   *最好就一致

         *c:父类静态方法,子类也必须通过静态方法进行重写

                   *其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解(静态只能覆盖静态)            

         *子类重写父类方法的时候,最好声明一模一样。

 

14.方法重写的习题练习

* A:方法重写的习题

         *Override 重写和Overload 重载  的区别?Overload能改变返回值类型吗?

         *overload可以改变返回值类型,只看参数列表

         *方法重写:子类中出现了和父类中方法声明一模一样的方法。与返回值类型有关,返回值是一致(或者是子父类)的

         *方法重载:本类中出现的方法名一样,参数列表不同的方法。与返回值类型无关。

         *子类对象调用方法的时候:

                   *先找子类本身,再找父类。

 

15.使用继承后的学生和老师案例

* A:案例演示

         *使用继承后的学生和老师案例    注:Test_person.java 一定要看!!!!!

class Test4_Person {

         publicstatic void main(String[] args) {

                   Students1 = new Student();

                   s1.setName("张三");

                   s1.setAge(23);

                   System.out.println(s1.getName()+ "..." + s1.getAge());

                   s1.eat();

                   s1.study();

         }  }

 

class Person {

         privateString name;                                              //姓名

         privateint age;                                                       //年龄

         //空参构造

         //有参构造

        //set或get方法.....

 

         publicvoid eat() {                                                    //吃饭

                   System.out.println(name  + "吃饭");

         }  }

 

class Student extends Person {

         publicStudent() {}    //空参构造

 

         publicStudent(String name,int age) {

                   super(name,age);        //注意点!!!!!!!

         }

 

         publicvoid study() {

                 System.out.println(this.getName()+ "学习");   //注意!!!此处不能用name,因为name我私有变量,或不加this.或super.都行

         }

}

class Teacher extends Person {

         publicTeacher() {}    //空参构造

 

         publicTeacher(String name,int age) {

                   super(name,age);        //注意点!!!!!!!

         }

         publicvoid teach() {

                   System.out.println(this.getName()+ "讲课");

         }

}

 

 

16.final关键字修饰类,方法以及变量的特点

* A:final概述

* B:final修饰特点

         *修饰类,类不能被继承  final class 类名 { }

         *修饰变量,变量就变成了常量,只能被赋值一次  final  int NUM=10; NUM的值只能直接访问,不能修改

         *修饰方法,方法不能被重写  public final void 方法名(){ }

* C:案例演示

         *final修饰特点

public static final double PI = 3.14; //final修饰变量叫做常量,一般会与publicstatic共用,直接用类名调用即可

//常量命名规范,如果是一个单词,所有字母大写,如果是多个单词,每个单词都大写,中间用下划线隔开

17.final关键字修饰局部变量

* A:案例演示

         *方法内部或者方法声明上都演示一下

         publicstatic void main(String[] args) {

                   finalint num = 10;

                   //num= 20;       //会报错,不能再给num赋值!!

                   System.out.println(num);

 

                   finalPerson p = new Person("张三",23);

                   //p= new Person("李四",24);   //会报错,不能赋值!!!

                   p.setName("李四");     //但可以通过set方法改变其属性值!!!

                   p.setAge(24);

 

                   System.out.println(p.getName()+ "..." + p.getAge());  /输出 李四...24

                   method(30);

                   method(10);   //因为方法调用完后就会弹栈,所以不影响下面的语句!!!

                   method(20);   //依次输出30,10,20

         }

         publicstatic void method(final int x) {

                   System.out.println(x);

         }

         *基本类型,是值不能被改变

         *引用类型,是地址值不能被改变,对象中的属性可以改变  //通过set方法可以改变其属性值

 

18.final修饰变量的初始化时机

*final修饰的成员变量的默认初始化值是无效值/的.

* A:final修饰变量的初始化时机

         *显示初始化               //final  int NUM=10;

         *在对象构造完毕前即可     //在构造方法中初始化


 

你可能感兴趣的:(java,编程,面向对象,计算机,黑马程序员)