学习笔记——day07(继承封装)

在这里插入图片描述

构造器

什么是构造器

在类中用来创建对象那个的方法称之为构造器 构造函数 构造方法

注意事项

1:构造器是一个特殊的方法:

        a:方法名称和类名相同
  		b:方法无返回值
  		c:在方法中无须显示return返回数据
  		d:构造器是允许方法重载的		
 		e:所有类默认情况下都会存在一个无参构造器,如果在当前类中显式的声明了构造器之后,无参构造器就不存在了

构造器的作用

构造器的作用就是用来创建对象的

  • 构造器的调用只能通过new关键词去调用
  • 当给一个类中的成员变量的类型声明为基本数据类型之后,导致基本数据类型存在默认值。
  • 未赋值的情况下存在值,后续的逻辑可能存在问题。

代码

/**
 * 找共性:
 * 		成员变量(属性)	姓名  学号  性别  班级
 * 		方法(功能)		学习 
 */
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+"]";
		
	}
	
	
}

引用类型进过方法

  • 基本数据类型经过方法之后 其值不变。值传递
  • 引用数据类型进过方法之后 其值会变,值传递(地址值)
  • 通过两个变量指向了同一个内存地址,一个对内存进行改变 另一个可见
  
   public class Test02 {
	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.info());
		
		
		change(d);
		System.out.println("main:"+d.info());
		
	}
	
	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.info());
	}
}


class Dog{
	
	String name;
	String color;
	
	public Dog() {
		
	}
	
	public void run() {
		System.out.println("run。。。。。");
	}
	
	public String info() {
		return "name:"+this.name+",color"+this.color;
	}
	
}

在这里插入图片描述

继承

在这里插入图片描述

继承的优势

  • 在一定程度上提高了代码的复用性

什么是继承

  • 子承父业, 将多个类中的共性再一次抽取,可以抽取为一个父类。父类的作用就是用来将一些重复的内容不再多次编写(提高代码复用性)

继承的编写

  • 子类 extends 父类 (子类拥有父类中的所有的属性以及方法)

继承的注意事项

  • java中只支持单继承 一个子类有且只能有一个父类 复用性的提高是有限的

  • Q:多继承好还是单继承好?

     多继承 :极大提高代码复用性 但是代码调用的复杂度也提升了
     单继承:代码调用的复杂度比较低,但是复用性比较有限
    

    假设在应用场景中:
    A->B 后期随着业务不断扩展,导致A需要继承C时一般的解决办法:A->B->C
    但是该种解决办法随着后期业务的不断升级,导致整个继承连会变得极其复杂,既不利于后期维护以及拓展。
    所以,能不能用继承就别用继承。

代码

Person类 主类:
package com.mage.oop.extend;

public class Person {
	
	String name;
	int age;
	int gender;
	
	public Person() {
	}
	
	
	public void eat() {
		System.out.println(this.name+"在吃饭");
	}
}


Student 类   子类:
package com.mage.oop.extend;

public class Student extends Person{
	int id;
	
	
	public Student() {

	}
	

	public void study() {
		System.out.println(this.name+"在学习");
	}
}


Teacher类 子类:
package com.mage.oop.extend;

public class Teacher extends Person{
	
	
	double sal;
	
	public Teacher() {
		
	}
	
	
	
	public void working() {
		System.out.println(this.name+"在工作");
	}
}


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 = 1000000000;
		
		t.eat();
		t.working();
	}
}


this&super

this

this的用法:
1. this.

当前对象的-》 谁在调用 代表谁

  • 可省略:
    不需要区分区分同名变量,局部变量和成员变量的时候可以省略
  • 不可省略:
    区分同名变量,局部变量和成员变量不可以省略
 \\为了区分同名变量这里的this 不能省略
public Student(String name) { 
		 this.name = name; 
	 }

	
2. this()
  • 构造器之间的互相调用
  • this()一定要在构造器的首行

super

  • 当创建子类对象时 会先执行父类的构造器

  • super: 和this的用法一模一样

  • super.
    表示当前对象的父类对象的

1.super.
  • 可省略的:
    super和this的用法是重复的 都可以省略
  • super. 不可省略
    如果子类和父类中出现了同名变量或者是同名方法
2.super()
  • 调用父类的构造器,默认情况下调用的父类的无参构造器(默认情况下每个类中都存再一个无参构造器 哪怕不写也存在)

  • 当父类中存在其他构造器时,无参构造器不存在,此时如果再子类中没有通过super()显示的指定调用的构造器会导致程序报错。

  • 在构造器中this()和super()不能同时出现,如果两个都不存在,默认是存在的super()。

代码
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 吃东西");
	}
	
}

在这里插入图片描述

重写方法

定义

在子类中定义了和父类中同名的方法 我们将该方法称之为重写方法(覆盖)

为什么需要重写?

父类的功能不能满足子类的需求。子类在父类的基础上进行了扩展。

如何确定一个方法是重写方法?

在子类的方法上加入@Overried 注解 如果不报错 证明是重写

重写的前提:

  • 一定要发生继承关系。并且子类的方法名和父类的方法名同名
  • 参数列表要一样
  • 返回类型要一样
代码
public class Test03 {
	public static void main(String[] args) {
		//创建一个子类对象
		S  s = new S();
		s.study();
		s.marry();
		s.work();
		
		
	}
	
	
}
/**
 *  爱情观
 * 
 */
class F{
	
	String name;
	public F() {
	}
	public int study() {
		System.out.println("好好学习 时间观念及其严苛");
		return 1;
	}
	
	public void marry() {
		System.out.println("赶紧结婚 我要抱孙子");
	}
	
	public void work() {
		System.out.println("赶紧去挣奶粉钱。。。。。");
	}
}

class S extends F{
	
	public S() {
	}
	
	@Override
	public int study() {
		System.out.println("开心很重要 开心的学习");
		return 1;
	}
	
}

object类

什么是object

Object: 是所有类的根基类 超类 父类

当一个类没有显式的继承关系的时候,默认情况下他的父类都是Object

  • Object:
ctrl+O 罗列当前类中的所有方法
finalize: gc回收垃圾时 自动调用finalize	
wait
notify
notifyAll
 	--- 学习多线程时候会讲
clone: 克隆    (创建对象的一种方式 深浅复制)
hashCode: 哈希码 -> 哈希算法	 唯一的值
getClass:获取当前类的Class对象  反射
  • 输出一个对象的时候默认情况下会调用当前对象的toString
==与equals的区别
  • == 比较基本数据类型比较的是值 比较引用类型比较的是地址
  • 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+"}";
	}
	
}

封装

四个修饰符

  • public 修饰的人见人爱型 都能访问 被public修饰的方法、类、变量能被所有类可见
  • protected 同包下可见 异包下子类可见
  • 默认的: 不写 远亲不如近邻 同包下可见 异包下不可见
  • private: 自私自利 本类可见
本类同包下子类同包下无关类异包子类异包无关类
public
protected×
默认的××
private××××
代码

本类

package com.mage.oop.box.china;

public class F {
	public  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 {
	private String name;
	
	public static void main(String[] args) {
		 LaoWang f = new LaoWang();
		 System.out.println(f.name);
	}
	
}

同包下子类

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;


public class LaoWang2 {
	public static void main(String[] args) {
		F f = new F();
		System.out.println("异包下的不同类访问public修饰的变量:"+f.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);
		
	}
}

修饰变量

局部变量只能通过final修饰

  • 1:将类中的成员变量通过public 默认的 protected 修饰之后,导致在某些情况下 可以随意.出来。这些修饰符修饰的变量不够安全。
  • 2:将这些变量通过private 修饰。但是导致无法正常访问
代码
public class Test01 {
	public static void main(String[] args) {
		
		// 创建一个Student 
		Student stu = new Student();
		
		//stu.age = 100;
		
		//System.out.println("stu的年龄是:"+stu.age);
		
		stu.setGender(3);
		
		System.out.println("stu的年龄是:"+stu.getGender());
		
		
	}
}

class Student{
	
	private int gender;
	private int age;
	
	public Student() {
	}
	
	
	

	public int getGender() {
		return gender;
	}

	public void setGender(int gender) {
		this.gender = gender;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	
	
	
}



class ArrayList{
	
	private int size;// 实际存储容量
	private int capacity;// 实际数组容量
	
	
	public int getSize() {
		return size;
	}
	public void setSize(int size) {
		this.size = size;
	}
	
}

修饰方法

修饰符的作用是用来屏蔽一些底层的实现逻辑,降低调用者(程序员)的复杂度。确保当前类更加安全。
修饰符可以修饰 类

  • 属性(成员变量) :
    避免随意.属性,修改获取属性 造成数据不安全
    如果用private修饰的话 一定要保证对外提供get、set方法让外部可见方法
  • 屏蔽底层调用细节,降低调用者(程序员)的复杂度 使得代码更加健壮
  • public private 比较常用
代码
计算水仙花数
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;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值