构造函数/构造方法
1.格式:与本类类名同名 且没有返回值类型
2.作用:创建对象
3.执行时机: 每次创建对象时 都会执行构造方法
4.类型:
- 无参构造:默认存在,但是一旦提供了其他的构造函数,默认的无参构造会被覆盖掉,所以需要手动提供
- 含参构造:含有参数的构造方法
- 全参构造:参数列表与本类所有属性一样 创建对象&给对象的所有属性赋值
构造代码块 局部代码块
-
代码块形式:
{代码…}
-
构造代码块的特点:
-
位置: 在类的内部,在方法的外部
-
作用: 用于抽取构造方法中的共性代码
-
执行时机: 每次调用构造方法前都会调用构造代码块
-
注意事项: 构造代码块优先于构造方法加载
-
-
局部代码块特点:
- 位置: 在方法里面的代码块
- 作用: 通常用于控制变量的作用范围,出了花括号就失效
- 注意事项: 变量的作用范围越小越好,成员变量会存在线程安全的问题
this
-
概念:
this代表本类对象的一个引用对象
-
形式:
比如: this.name=name
- 当本类成员变量与局部变量同名时,使用this指定成员变量
- 使用this在构造方法的第一行调用构造方法的功能
- this();–调用的是本类的无参构造
- this(参数);–调用的是本类对应参数的构造方法
- -注意:this关键字必须写在构造函数的第一行
- 调用是单项的 不能来回双向调用 否则会死循环
继承
-
概念:
继承是面向对象最显著的一个特征
继承是从已有的类中派生出新的类,新类能吸收已有类的数据属性和行为,并扩展新的能力.
Java继承是会用已存在的类的定义作为基础建立新类的技术
新类的定义可以增加新的数据或者新的功能,也可以使用父类的功能,但不能选择性的继承父类(超类/基类)
这种继承使得复用以前的代码非常容易,能够大大的缩短开发的周期,降低开发费用 -
- 继承的关键字extends 格式: 子类 extends 父类
- 继承相当于子类把父类的功能复制了一份
- Java只支持单继承:一个子类只能有一个父类,一个父类可以有多个子类
- 继承具有传递性:爷爷的功能会传给爸爸,爸爸的功能会传给孙子
- 子类只可以使用父类的非私有资源,私有资源由于private限制,不可用
- 子类可以拥有自己的特有功能
- 继承是is a 强耦合的关系,依赖性非常强,比如我们看到”熊孩子”,就知道他有一个”熊父母
-
继承中的构造方法
-
子类在创建对象时,默认会先调用父类的构造方法
-
原因是子类构造函数中的第1行默认存在super();–表示调用父类的无参构造
-
当父类没有无参构造时,可以通过super(参数);调用父类的其他含参构造
注意:子类必须调用父类的一个构造函数,不论是无参还是含参,选一个即可 -
构造方法不可以被继承!因为语法的原因,要求构造方法的名字必须是本类类名
不能在子类中出现一个父类名字的构造方法
-
super
- 当父类的成员变量与子类的变量同名时,使用super指定父类的成员变量
- 使用super在子类构造方法的第一行调用父类构造方法的功能
- super();–调用的是父类的无参构造
- super(参数);–调用的是父类对应参数的构造方法
案例一
package cn.tedu.review;
/**程序一 本类用于面向对象的知识回顾*/
public class TestCar {
public static void main(String[] args) {
//4.创建汽车类对象c
Car c = new Car();
//5.给c对象的属性赋值 并且打印查看结果 "宝马" "活力橙" 200000.98 3.1
// c.brand="宝马";
// c.color="活力橙";
// c.price=200000.98;
// c.length=3.1;
// System.out.println(c.brand);
// System.out.println(c.color);
// System.out.println(c.price);
// System.out.println(c.length);
//8.通过set方法给c对象重新赋值 "特斯拉" "石墨绿" 210000.99 2.9
c.setBrand("特斯拉");
c.setColor("石墨绿");
c.setPrice(210000.99);
c.setLength(2.9);
System.out.println(c.getBrand());
System.out.println(c.getColor());
System.out.println(c.getPrice());
System.out.println(c.getLength());
//6.通过c对象调用c对象的方法
c.start();
//10 c.stop();
}
}
//1.定义汽车类
class Car{
//2.定义汽车属性 品牌 颜色 价格 车长
//7.封装属性
private String brand;
private String color;
private double price;
private double length;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
//3.定义汽车类的方法
//10 封装并调用stop方法并调用
public void start(){
System.out.println("汽车启动");
stop();//在本类的公共方法里调用这个私有方法
}
private void stop(){
System.out.println("汽车停止");
}
}
案例二
package cn.tedu.oop;
import java.util.Arrays;
/**程序二 本类用于测试构造方法*/
public class TestConstructor {
public static void main(String[] args) {
//4.创建persion类对象 并进行测试
/*1.每一个类中 默认都会存在一个没有参数的构造方法
* 每次new(实例化)对象时,都会自动触发这个类对应的构造方法来帮助我们创建对象*/
Persion p = new Persion();
System.out.println(p.name);
System.out.println(p.age);
System.out.println(p.address);
p.eat();
//6.创建persion类的第二个对象
/*3.每次创建对象时 都会执行构造方法
*构造方法的作:用来创建对象*/
Persion p2 = new Persion();
//8.创建persion类的第三个对象 触发 含参构造
Persion p3 = new Persion(88);//括号里n是idea自动匹配的 不需要自己写
//10 创建persion类的第四个对象 触发 全参构造
Persion p4 = new Persion("李逵",32,"柳树下");
//11 查看p4对象的属性值 是否复制成功
System.out.println(p4.name);
System.out.println(p4.age);
System.out.println(p4.address);
//12 查看p3对象的属性值 是否复制成功
System.out.println(p3.name);
System.out.println(p3.age);
System.out.println(p3.address);
}
}
//1.创建一个persion类 用来描述 人 这一类事物
class Persion{
//2.提供persion 属性 姓名 年龄 住址
String name;
int age;
String address;
/*2.写构造方法
* 格式: 没有返回值类型 并且 与本类类名同名的方法*/
//5.构建本类的无参构造
/*4.如果提供了其他的构造函数,默认的无参构造函数就会被覆盖,不存在了
* 所以,如果想不传参数创建对象的话,需要我们手动提供这个无参构造*/
public Persion(){
System.out.println("我是persion类的无参构造");
}
//7.创建本类的含参构造
public Persion(int n){
System.out.println("我是persion类的含参构造"+n);
}
//9.创建本类的全参构造
public Persion(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
System.out.println("我是persion类的全参构造");
}
//3.功能---方法
public void eat(){
System.out.println("干饭不积极,思想有问题~~");
}
}
案例三
package cn.tedu.oop;
/**程序三 */
public class TestConstructor2 {
public static void main(String[] args) {
//6.1 无参构造创建对象
Student s1=new Student();
//6.2 含参构造创建对象
Student s2=new Student("哈哈哈");
//6.3 全参构造创建对象
Student s3=new Student("张三",'男',"抬杠",100);
System.out.println(s1.name);//null
System.out.println(s2.name);//null
System.out.println(s3.name);//张三
System.out.println(s3.gender);
System.out.println(s3.major);
System.out.println(s3.score);
}
}
//1.创建学生类Student
//2.属性: name 性别gender 专业major 成绩score
class Student{
String name;
char gender;
String major;
double score;
//3.无参
public Student(){
System.out.println("我是Student的无参构造");
}
//4.含参
public Student(String s){
System.out.println("我是Student的含参构造:"+s);
}
//5.全参
/*右键 Generate Constructor 选择 确定*/
public Student(String name, char gender, String major, double score) {
this.name = name;
this.gender = gender;
this.major = major;
this.score = score;
System.out.println("我是Student的全参构造");
}
}
案例四
package cn.tedu.oop;
/**四 本类用于测试代码块*/
public class TestBlock {
public static void main(String[] args) {
//System.out.println(666);//如果只是业务操作 没有创建对象 是不会执行构造方法的
Pig p1 = new Pig();
Pig p2 = new Pig("中午好");
Pig p3 = new Pig("菜叶子和水果",3);
p1.eat();
}
}
//1.创建一个小猪类用来测试
class Pig{
//2.属性
String food;
int age;
//4.创建本类的构造代码块
{
/**构造代码块:{}
* 1.位置:类里方法外
* 2.执行时机:每次创建对象时都会执行构造代码块,并且构造代码块优先于构造方法执行
* 3.作用:用于提取所有构造方法中的共性功能代码*/
System.out.println("我是一个构造代码块~~");
System.out.println("黑猪肉");
}
//5.提供小猪类的 无参 含参 全参
public Pig(){
System.out.println("无参构造");
// System.out.println("黑猪肉");
}
public Pig(String s){
System.out.println("含参构造");
//System.out.println("黑猪肉");
}
public Pig(String food,int age){
this.food=food;
this.age=age;
System.out.println("全参构造");
// System.out.println("黑猪肉");
}
//3.定义方法
public void eat(){
System.out.println("小猪爱吃菜叶子");
//创建局部代码块
{/**局部代码块:{}
*1.位置:方法里
* 2.执行时机:调用局部代码块所处的方法时才会执行
* 3.作用:用于控制变量的作用范围 变量的作用范围越小越好
*/
System.out.println("我是一个局部代码块");
int i =10;
System.out.println(i);
}
//System.out.println(i); 错误的 出了局部代码块就不能用了
}
}
案例五
package cn.tedu.oop;
/** 五*/
public class TestCat {
public static void main(String[] args) {
//9
Cat c1 = new Cat();
c1.setAge(300);
c1.setHost("大熊");
c1.setKind("机器猫");
c1.setPrice(10000);
c1.setName("叮当");
System.out.println(c1.getName());
System.out.println(c1.getAge());
System.out.println(c1.getKind());
System.out.println(c1.getHost());
System.out.println(c1.getPrice());
//10
Cat c2 = new Cat("罗小黑",7,"变异猫","未知",800);
System.out.println(c2.getName());
System.out.println(c2.getAge());
System.out.println(c2.getKind());
System.out.println(c2.getHost());
System.out.println(c2.getPrice());
//11
Cat c3 = new Cat("达芬奇",5,"布偶猫","龙哥",800000);
c3.eat(2);
c3.jump("达芬奇");
c3.play("龙哥");
c3.sleep("达芬奇",8);
}
}
class Cat{
//1.定义小猫类
//2.属性
//3.封装 创建所有get set
//4.构造 无参 含参 全参
//5.提供功能 1吃 eat参数int n无返回值 打印 小猫今天吃"+n+"根骨头 2 跳 jump 参数String name 无返回值 打印 小猫"+name+"跳的老高了
//6.提供功能 1)睡觉sleep 参数:String name,double num无返回值 打印 小猫name今天一共睡了num个小时
// 2)玩play 参数:String host, 返回值String"逗猫棒",打印 小猫与主人host玩的很开心
//7.叫 bark 打印 小猫喜欢喵喵叫 此方法要封装,玩的时候才叫
//8.完成业务:每当创建小猫类的对象,就在控制台打印:又有一只可爱的小猫咪出来了
//9. 创建小猫类的对象c1 使用无参构造创建 并调用set()给c1赋值 :叮当 300 机器猫 大熊 1000 并查看
//10 使用全参构造小猫类对象c2,赋值:罗小黑 7 变异猫 未知 800 并查看
//11 创建小猫类对象c3 通过c3对象 调用小猫类的5个工能
private String name;//名字
private int age;//年龄
private String kind;//品种
private String host;//主人
private double price;//价格
//8 构造代码块
{
System.out.println("又有一只可爱的小猫咪出来了");
}
//3
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
//4.无参 含参 全参
public Cat(){
System.out.println("无参");
}
public Cat(String s){
System.out.println("含参");
}
public Cat(String name, int age, String kind, String host, double price) {
this.name = name;
this.age = age;
this.kind = kind;
this.host = host;
this.price = price;
System.out.println("全参");
}
//5
public void eat(int n){
System.out.println("小猫今天吃"+n+"根骨头");
}
public void jump(String name){
System.out.println("小猫"+name+"跳的老高了");
}
//6
public void sleep(String name,double num){
System.out.println("小猫"+name+"今天一共睡了"+num+"个小时");
}
public String play(String host){
System.out.println("小猫与主人"+host+"玩的很开心");
bark();//7
return "逗猫棒";
}
//7
private void bark(){
System.out.println("小猫喜欢喵喵叫");
}
}
案例六
package cn.tedu.oop2;
import sun.util.resources.cldr.ta.TimeZoneNames_ta;
/**六 本类用于this测试*/
public class TestThis {
public static void main(String[] args) {
//4 创建对象并调用方法eat()
Dog d1 = new Dog();
d1.eat();
}
}
//1.创建小狗类
class Dog{
//2.属性 成员变量
int count = 666;
int sum =100;
//3.创建方法
public void eat(){
//System.out.println(sum);
// System.out.println(count);
// 5.在eat()方法中创建局部变量sum
int sum=10;
System.out.println(sum);//使用局部变量 就近原则 打印10
/*当成员变量与局部变量同名时 可以使用this关键字指定本类的成员变量
* 如果不使用this指定 打印的就是近处的这个局部变量,就近原则*/
System.out.println(this.sum);//100
System.out.println(count);//666
}
}
案例七
package cn.tedu.oop2;
/**七 本类用于测试this的用法2*/
public class TestThis2 {
public static void main(String[] args) {
//3.1创建无参对象c1
Cat c1 = new Cat();
//3.2 创建含参对象c2
Cat c2 = new Cat("下午好");
}
}
//1.创建小猫类
class Cat{
//2.1 无参构造
public Cat(){
/*表示在无参构造中调用含参构造的功能
* 注意:调用是单项的 不能来回双向调用 否则会死循环*/
this("你好");
System.out.println("无参构造");
}
//2.2 含参 String s
public Cat(String s){
/*表示在含参构造中 调用无参构造的功能
*规定:this关键字必须写在构造函数的第一行*/
//this();
System.out.println("含参构造:"+s);
}
}
案例八
package cn.tedu.oop2;
import jdk.management.resource.internal.inst.SocketOutputStreamRMHooks;
/**八 本类用于继承的入门案例*/
public class TestExtends {
public static void main(String[] args) {
//5.分别创建三个类的对象
Fruit f = new Fruit();
Apple a = new Apple();
HFS h = new HFS();
//6.利用对象调用方法进行测试
/*3.继承相当于是子类将父类的资源复制了一份
* 继承还具有传递性 爷爷的功能会传给爸爸 爸爸的功能会传给孙子*/
f.eat();//爷爷类的对象使用自己的方法
a.eat();//爸爸类的对象使用从爷爷那里继承来的方法
h.eat();//孙子类的对象使用从爸爸那里继承来的方法
h.sweet();//10,红富士特别甜~
}
}
/*1.我们通过extends关键字建立子类和父类的继承关系,格式:子类 extends 父类
*2. 并且 Java只支持单继承 一个子类只能继承一个父类 但是 一个父类可以被多个子类继承*/
//1.创建水果类 --- 爷爷类
class Fruit{
//4.添加爷爷类的普通方法
public void eat(){
System.out.println("现在还没想好吃啥水果");
}
}
//2. 创建苹果类---爸爸类
/*6.继承是一种 is a 的关系 比如 苹果是一种水果 红富士是一种苹果
* 继承要求 子类必须是父类的一种下属类型 依赖性非常强 强耦合*/
class Apple extends Fruit{
//7.定义爸爸类中的属性
int a = 10;//普通属性
private int b =100;//私有属性
}
//3.创建红富士类--孙子类
class HFS extends Apple{
//8.定义孙子类独有的方法
/*4.子类可以拥有自己独有的方法 实现功能拓展 青出于蓝而胜于蓝*/
public void sweet(){
System.out.println(a);//可以使用从父类继承过来的属性
System.out.println("红富士特别甜~");
/*5.子类继承了父类以后 可以使用父类的所有非私有资源
* 注意:这个私有资源由于有private修饰 所以没有访问权限*/
//System.out.println(b); 报错 b是私有资源
}
}
案例九
package cn.tedu.oop2;
/** 九 本类用于测试继承中 变量的使用*/
public class TestExtends1 {
public static void main(String[] args) {
//8 创建对象 调用study
Son s = new Son();
s.study();//100,10,2,1
}
}
//1.创建父类
class Father{
//2.创建父类成员变量
int sum = 1;
int count=2;
}
//3.建立子类
class Son extends Father{
//4.创建子类成员变量
int sum =10;
//5.创建子类普通方法
public void study(){
System.out.println("good good study,day day up");
//6.创建子类的局部变量
int sum=100;
//7.1打印子类的局部变量sum
System.out.println(sum);
//7.2打印子类的成员变量sum
System.out.println(this.sum);
//7.3打印父类的成员变量count
System.out.println(count);
//9 打印父类成员变量sum
/*当父类的成员变量与子类的成员变量同名时,可以使用super关键字指定父类的成员变量
* 可以把super看作是父类的对象:Father super=new Father();*/
System.out.println(super.sum);//super用法1
}
}
案例十
package cn.tedu.oop2;
/** 十 本类用于测试继承中 构造方法的使用
* 1.子类在创建对象时,默认会先调用父类的构造方法
* 2.原因是 子类构造函数中的第一行默认存在super();--表示调用父类的无参构造
* 3.当父类没有无参构造时可以通过super(参数);调用父类的其他含参构造
* 注意:子类必须调用父类的一个构造函数,不论是无参还是含参,选一个即可
* 4.构造方法是不能被继承的,因为语法的原因 要求构造方法的名字必须是本类名
* 不能在子类中出现一个父类名字的构造方法
* */
public class TestExtends2 {
public static void main(String[] args) {
//6.1通过父类的无参构造 创建父类的对象
Father2 f1 = new Father2(); //我是父类的无参构造
//6.2通过父类的含参构造 创建父类的对象
Father2 f2 = new Father2("傍晚好~~");//我是父类的含参构造傍晚好~~
//6.3 创建子类对象
Son2 s = new Son2();//我是父类的无参构造 + 我是子类的无参构造
}
}
//1.创建父亲
class Father2{
//3.父类无参构造
public Father2(){
System.out.println("我是父类的无参构造");
}
//4.父类含参构造
public Father2(String s){
System.out.println("我是父类的含参构造"+s);
}
}
//2.创建子类
class Son2 extends Father2{
//5.子类的无参构造
public Son2(){
// super();//调用父类的无参构造 是默认存在的 平时看不见
super("哈哈哈");//当父类没有无参构造时可以通过super(参数);调用父类的其他含参构造 子类必须调用父类的一个构造函数,不论是无参还是含参,选一个即可
System.out.println("我是子类的无参构造");
}
}