------- 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;
*在对象构造完毕前即可 //在构造方法中初始化