JAVA基础 day07
构造器
定义:
在类中用来创建对象那个的方法称之为构造器,|| 构造函数,构造方法
一个特殊的方法:
a).方法名称和类名相同
b).方法无返回值;
c).在方法中无须显示的return返回数据。
d).构造器是允许方法重载
e).所有的类默认情况下都会存在一个无参构造器,如果在当前类中显式的声明了构造器之后,无参构造器就不存在了
作用:
用来创建对象的
**构造器的调用只能通过new关键词去调用**
tips:
当给一个类中的成员变量的;类型声明为基本数据类型之后,导致基本数据类型存在默认值。
- 未赋值的情况下存在值,后续的逻辑可能存在问题。
public class Student {
static int count = 1;
int id;
String name;
int gender;// 0 代表男 1代表女
String clz;
public Student() {
this("张三");
System.out.println("我被调用了。。。。");
//study();
}
public Student(String name) {
this.name = name;
}
public Student(String name,int gender) {
this(name,gender,count++,"0708");
}
public Student(String name,int gender,int id,String clz) {
this.name = name;
this.gender = gender;
this.id = id;
this.clz = clz;
}
public void study() {
System.out.println(this.name+"day day up");
System.out.println(this.info());
}
public String info() {
return "Student[id:"+this.id+",name:"+this.name+""
+ ",gender:"+(this.gender==0?"男":"女")+",clz:"+this.clz+"]";
}
}
this的用法
1. this.
当前对象的-》 谁在调用 代表谁
- 可省略:
- 不可省略:
区分同名变量,局部变量和成员变量
2. this()
构造器之间的互相调用
**this()一定要在构造器的首行**
tips:
- 基本数据类型经过方法之后 其值不变。值传递
- 引用数据类型进过方法之后 其值会变,值传递(地址值)
- 通过两个变量指向了同一个内存地址,一个对内存进行改变 另一个可见
封装
4个关键字
public 修饰的人见人爱型 都能访问 被public修饰的方法、类、变量能被所有类可见
- protected 同包下可见 异包下子类可见
- 默认的: 不写 远亲不如近邻 同包下可见 异包下不可见
- private: 自私自利 本类可见
- 本类 同包下子类 同包下无关类 异包子类 异包下无关类
- public √ √ √ √ √
- protected √ √ √ √ ×
- 默认的 √ √ √ × ×
- private √ × × × ×
tips:
如果某个类要使用时 该类不在当前包下 需要导包 import 包名.类名;
public class LaoWang2 {
public static void main(String[] args) {
F f = new F();
System.out.println("异包下的不同类访问public修饰的变量:"+f.name);
}
}
package com.mage.oop.box.china;
public class F {
private String name;
public static void main(String[] args) {
F f = new F();
System.out.println(f.name);
}
}
package com.mage.oop.box.china;
public class LaoWang {
public static void main(String[] args) {
F f = new F();
System.out.println("访问同包下的无关类public修饰的变量:"+f.name);
}
}
package com.mage.oop.box.china;
public class S1 extends F{
public static void main(String[] args) {
S1 s = new S1();
System.out.println("通过同包下的子类对象方法父类中的public修饰的变量:"+s.name);
}
}
package com.mage.oop.box.EN;
import com.mage.oop.box.china.F;
/*
* 如果某个类要使用时 该类不在当前包下 需要导包 import 包名.类名;
*/
public class S2 extends F {
public static void main(String[] args) {
S2 s = new S2();
System.out.println("异包下的子类对象访问父类中public修饰的变量:"+s.name);
}
}
继承
定义:
继承的优势:
-
在一定程度上提高了代码的复用性
-
继承编写:
-
子类 extends 父类 子类拥有父类中的所有的属性以及方法
-
什么是继承: 子承父业,
-
将多个类中的共性再一次抽取,可以抽取为一个父类。父类的作用就是用来将一些重复的内容不再多次编写(提高代码复用性)
-
注意事项:
-
java中只支持单继承 一个子类有且只能有一个父类 复用性的提高是有限的
-
多继承好还是单继承好
-
多继承 :极大提高代码复用性 但是代码调用的复杂度也提升了
-
单继承:代码调用的复杂度比较低,但是复用性比较有限
-
假设在应用场景中:
-
A->B 后期随着业务不断扩展,导致A需要继承C时一般的解决办法:A->B->C
-
但是该种解决办法随着后期业务的不断升级,导致整个继承连会变得极其复杂,既不利于后期维护以及拓展。
-
能不能用继承就别用继承。
public class Test01 {
public static void main(String[] args) {
// 创建一个子类对象
Dog d = new Dog();
//d.lookDoor();
}
}
class Animal{
String name;
public Animal() { System.out.println(" Animal 我被调用了......."); }
public Animal(String name) {
this.name = name;
System.out.println(" Animal 带参构造器 我被调用了.......");
}
public void eat() {
System.out.println("animal 吃东西");
}
}
class Dog extends Animal{
String nickName;
public Dog() {
this("呵呵");
System.out.println(" DOG 我被调用了。。。");
}
public Dog(String nickName) {
//super("hehe");
this.nickName = nickName;
System.out.println("DOG 才参数的");
}
public void lookDoor() {
System.out.println("看门");
super.eat();
}
public void eat() {
System.out.println("dog 吃东西");
}
}
super
- 当创建子类对象时 会先执行父类的构造器
- super: 和this的用法一模一样
- super.
- 当前对象的父类对象的
- super. 可省略的:
- super和this的用法是重复的 都可以省略
- super. 不可省略
- 如果子类和父类中出现了同名变量或者是同名方法
- super()
- 调用父类的构造器,默认情况下调用的父类的无参构造器(默认情况下每个类中都存再一个无参构造器 哪怕不写也存在)
- 当父类中存在其他构造器时,无参构造器不存在,此时如果再子类中没有通过super()显示的指定调用的构造器会导致程序报错。
- 在构造器中this()和super()不能同时出现,如果两个都不存在,默认是存在的super()。
重写
- 在子类中定义了和父类中同名的方法 我们将该方法称之为重写方法(覆盖)
-
- 为什么需要重写?
- 父类的功能不能满足子类的需求。子类在父类的基础上进行了扩展。
- 如何确定一个方法是重写方法?
- 在子类的方法上加入@Overried 注解 如果不报错 证明是重写
- 重写的前提:
- 一定要发生继承关系。并且子类的方法名和父类的方法名同名
- 参数列表要一样
- 返回类型要一样
Object
Object: 是所有类的根基类 超类 父类
- 当一个类没有显式的继承关系的时候,默认情况下他的父类都是Object
- Object:
- ctrl+O 罗列当前类中的所有方法
- finalize: gc回收垃圾时 自动调用finalize
- wait
- notify
- notifyAll
- — 学习多线程时候会讲
- clone: 克隆 (创建对象的一种方式 深浅复制)
- hashCode: 哈希码 -> 哈希算法 唯一的值
- getClass:获取当前类的Class对象 反射
- 输出一个对象的时候默认情况下会调用当前对象的toString
- == 比较基本数据类型比较的是值 比较引用类型比较的是地址
- equals:用来比较相等的 如果相等返回true 反之返回false
- Object中的比较是通过==比较的
public class Test04 {
public static void main(String[] args) {
//创建一个Test04 对象
Test04 t = new Test04();
//创建一个Bird对象
Bird b = new Bird();
System.out.println(b);
System.out.println(b.toString());
// 创建一个bird对象
Bird b1 = new Bird();
// 比较相等的
boolean flag = b.equals(b1);
System.out.println(flag);
}
}
class Bird{
String color;
String type;
public Bird() {
}
@Override
public String toString() {
return "Bird{color:"+this.color+",type:"+this.type+"}";
}
}
final
局部变量只能通过final修饰
- 1:将类中的成员变量通过public 默认的 protected 修饰之后,导致在某些情况下
- 可以随意.出来。这些修饰符修饰的变量不够安全。
- 2:将这些变量通过private 修饰。但是导致无法正常访问
重点
修饰符的作用是用来屏蔽一些底层的实现逻辑,降低调用者(程序员)的复杂度。
- 确保当前类更加安全。
- 修饰符可以修饰 类
- 属性(成员变量) :
- 避免随意.属性,修改获取属性 造成数据不安全
- 如果用private修饰的话 一定要保证对外提供get、set方法让外部课件
- 方法
- 屏蔽底层调用细节,降低调用者(程序员)的复杂度 使得代码更加健壮
- public private
public class Test03 {
public static void main(String[] args) {
System.out.println(FlowerUtil.isFlower(92727));
}
}
package com.mage.oop.test;
public class FlowerUtil {
public static boolean isFlower(int num) {
//获取累加的和
int sum = sum(num);
return num==sum;
}
private static int sum(int num) {
//声明存放累加的结果
int result = 0;
// 声明一个方法 计算一个数字的长度 位数
int length = length(num);
while(num!=0) {
//分离每一位
int bit = num%10;
result = result+pow(bit,length);
num = num/10;
}
return result;
}
public static int pow(int bit,int length) {
int result = 1;
for(int i = 1;i<=length;i++) {
result = result*bit;
}
return result;
}
public static int length(int num) {
int length = 0;
while(num!=0) {
num = num/10;
length++;
}
return length;
}
}