面向对象(2)
一·本章重点:
二·构造器:
含义:
在类中用来创建对象那个的方法称之为构造器 构造函数 构造方法 .
特点:
*(1)方法的名称和类名是一样的;
(2)没有返回值,不用在方法中显示return返回语句;
(3)是允许重载的;
(4)一般情况下会有一个无参构造器,但是要是类中显示声明了构造器,无参构造器就不存在了。
作用:
构造器的作用就是用来创建对象的
注意:
- 构造器的调用只能通过new关键词去调用
- 当给一个类中的成员变量的;类型声明为基本数据类型之后,导致基本数据类型存在默认值。 未赋值的情况下存在值,后续的逻辑可能存在问题。
例题1分析:
1.package com.mage.oop;
2.public class Student {
3. int stuno;
4. String name;
5. int sex;
6. String cls;
7. //构造方法
8. public Student(){
9. this("大萌萌");
10. System.out.println("大萌。。。。");
11. }
12. public Student(String name) {
13. this.name = name;
}
14. public Student(String name,int sex,int stuno,String cls) {
15. this.name = name;
16. this.sex = sex;
17. this.stuno = stuno;
18. this.cls = cls;
19. }
20. public void study() {
21. System.out.println(this.name+"天天打代码");
22. }
23. public String toString() {
24. return "Student[学号:"+this.stuno+",姓名:"+this.name+""
25. + ",性别:"+(this.sex==0?"男":"女")+",班级:"+this.cls+"]";
26. }
27.}
测试类:
1.package com.mage.oop;
2.public class test1 {
3. public static void main(String[] args) {
4. //通过无参构造器创建Stu对象
5. Student stu = new Student();
6. stu.stuno = 1;
7. stu.name = "大萌";
8. stu.sex = 1;
9. stu.cls = "0708";
10. stu.study();
11. System.out.println(stu.name);
12. //通过带参构造器创建Stu对象
13. Student stu3 = new Student("大萌萌");
14. stu3.study();
15. }
16.}
内存分析图:
三·this的用法:
(1)this.:当前对象(谁在调用就代表谁);在区分同名变量时不可以省略;(在局部变量和成员变量)
(2)this():构造器之间的相互调用;this()一定要在构造器的首行。
例1详图:
四·super的用法:
(1)super.:当前对象的父类对象的;在区分同名变量或者同名方法时不可以省略;(在子类和父类出现了同名变量或者是同名方法)
(2)super():构造器之间的相互调用调用的是父类的构造器;默认的情况下调用的是父类的无参构造器(默认存在就算没有写也默认有,父类中存在其它构造器时无参构造器不存在,此时如果在子类中美没有通过super()显示的指定调用的构造器会导致程序出错。
注意:
*在构造器中this()和super()不能同时出现,若两个都不存在,则默认的是super()。
五·引用类型进过方法:
(1)基本数据类型经过方法之后 其值不变。值传递
(2)引用数据类型进过方法之后 其值会变,值传递(地址值)
(3)通过两个变量指向了同一个内存地址,一个对内存进行改变 另一个可见
例题2分析:
package com.mage.test;
public class Dog {
String name;
String color;
public Dog(){
}
public void run(){
System.out.println("gouhuipao");
}
public String toString(){
return "name"+this.name+",color"+this.color;
}
}
test类:
package com.mage.test;
public class test2 {
public static void main(String[] args) {
int num = 10;
change(num);
System.out.println("main:"+num);
//声明一个dog对象
Dog d = new Dog();
d.color = "黑色"; d.name = "黑妹";
System.out.println(d.toString());
change(d);
System.out.println("main:"+d.toString());
}
public static void change(int num) {
num++;
System.out.println("change:"+num);
}
public static void change(Dog dog) {
dog.name = "旺财";
dog.color = "黄色";
System.out.println("change:"+dog.toString());
}
}
运行结果:
调用内存分析图:
六·继承:
图解:
优势:
在一定程度上提高了代码的复用性 .
注意:
*java中只支持单继承 一个子类有且只能有一个父类 复用性的提高是有限的
多继承好还是单继承好 ?
* 多继承 :极大提高代码复用性 但是代码调用的复杂度也提升了
* 单继承:代码调用的复杂度比较低,但是复用性比较有限
* 假设在应用场景中:
* A->B 后期随着业务不断扩展,导致A需要继承C时一般的解决办法:A->B->C
* 但是该种解决办法随着后期业务的不断升级,导致整个继承连会变得极其复杂,既不利于后期维护以及拓展。
* 能不能用继承就别用继承。
例题3分析:
1.Person类:
package com.mage.test;
public class Person {
public String name;
int age;
public Person(){
}
public void eat(){
System.out.println("我在吃饭");
}
}
2.Teaher类:
package com.mage.test;
public class Teacher extends Person{
int sal;
public Teacher() {
}
public void work() {
System.out.println(this.name+"在工作");
}
}
3.Student类:
package com.mage.test;
public class Student extends Person{
int id;
public Student() {
}
public void study() {
System.out.println(this.name+"在学习");
}
}
4.Test类:
package com.mage.test;
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.name = "大萌萌";
stu.eat();
stu.study();
Teacher t = new Teacher();
t.name = "鹏鹏";
t.sal = 10000;
t.eat();
t.work();
}
}
运行结果:
七·方法重写:
定义:
在子类中定义了和父类中同名的方法 我们将该方法称之为重写方法(覆盖)
重写前提:
一定要发生继承关系,并且子类的方法名和父类方法名同名;
参数列表要一样,返回类型也要一样。
什么情况下发生重写:
1:发生继承
2:方法名同名
3:参数列表要一模一样 (顺序 个数 类型)
4:子类的返回值类型<=父类的返回值类型(引用) 基本类型一模一样
5:子类的修饰符>=父类的修饰符 (父类中的修饰符不能是private)
6:子类抛出的异常<=父类抛出的异常 (理解:可以认为任意一个方法都会对外抛出运行时异常)
如何确定:
在子类的方法上加上@Override注解如果不报错就是重写。
八·Object:
是所有类的基类、超类、父类、当一个类没有显示的继承关系的时候,默认情况下父类都是Object。
例题5分析:
package com.mage.oop;
public class Student {
int stuno;
String name;
int sex;
String cls;
//无参构造器
public Student(){
this("大萌萌");
System.out.println("大萌。。。。");
}
//带参构造器
public Student(String name) {
this.name = name;
}
public Student(String name,int sex,int stuno,String cls) {
this.name = name;
this.sex = sex;
this.stuno = stuno;
this.cls = cls;
}
//方法
public void study() {
System.out.println(this.name+"天天打代码");
}
public String toString() {
return "Student[学号:"+this.stuno+",姓名:"+this.name+""+ ",性别:"+(this.sex==0?"男":"女")+",班级:"+this.cls+"]";
}
}
封装:
四个修饰符的可见度:
本类 | 同包子类 | 同包无关类 | 异包子类 | 异包无关类 | |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protecred | Y | Y | Y | Y | N |
默认的 | Y | Y | Y | N | N |
private | Y | N | N | N | N |
修饰符作用:
(1)用来屏蔽一些底层的实现逻辑,降低调用者的复杂度,确保当前类更加安全;
(2)可修饰类:
(3)修饰属性(成员变量):避免随意.属性,修改获取属性造成数据不安全。
(4)修饰方法:屏蔽了底层的调用细节,降低了调用者的复杂性使得代码更加健壮。