初识面向对象
1. 构造方法
构造方法:类中的特殊方法,主要用于创建对象。
特点:
名称与类名完全相同。
没有返回值类型。
创建对象时,触发构造方法的调用,不可通过句点手动调用。
1.1 无参构造
注意:如果没有在类中显示定义构造方法,则编译器默认提供无参构造方法。
如果书写了有参构造方法,无参构造将被覆盖,如需使用,必须显式书写。
package com.atguigu.test1;
/**
* @author WHD
* @description TODO
* @date 2022/9/9 9:15
* 构造方法:类中的特殊方法,主要用于创建对象。
*
* 特点:
* 名称与类名完全相同。
* 没有返回值类型。
* 创建对象时,触发构造方法的调用,不可通过句点手动调用。
*
* 注意:如果没有在类中显示定义构造方法,则编译器默认提供无参构造方法。
*
* 构造方法重载:同一个类中的构造方法,参数列表不同
*/
public class Student {
String name;
int age;
double height;
char sex;
public void print(){
System.out.println("学生的名字是:" + name + ",年龄是:" + age);
System.out.println("身高是:" + height + ",性别是:" + sex);
}
public Student(){
System.out.println("Student类无参构造执行了");
}
public static void main(String[] args) {
Student stu1 = new Student();
stu1.name = "赵四";
stu1.age = 20;
stu1.height = 188;
stu1.sex = '男';
stu1.print();
}
}
1.2 有参构造
分析:以上创建对象 通过 对象名给属性一个一个赋值 每一个属性单独写一行
能不能统一给属性赋值?可以的 通过有参构造方法如果书写了有参构造方法,无参构造将被覆盖,如需使用,必须显式书写。
package com.atguigu.test1;
/**
* 构造方法:类中的特殊方法,主要用于创建对象。
*
* 特点:
* 名称与类名完全相同。
* 没有返回值类型。
* 创建对象时,触发构造方法的调用,不可通过句点手动调用。
*
* 注意:如果没有在类中显示定义构造方法,则编译器默认提供无参构造方法。
*
* 构造方法重载:同一个类中的构造方法,参数列表不同
*/
public class Student {
String name;
int age;
double height;
char sex;
public void print(){
System.out.println("学生的名字是:" + name + ",年龄是:" + age);
System.out.println("身高是:" + height + ",性别是:" + sex);
}
public Student(){
System.out.println("Student类无参构造执行了");
}
public Student(String n,int a,double h,char s){
name = n;
age = a;
height = h;
sex = s;
}
public static void main(String[] args) {
Student stu1 = new Student();
stu1.name = "赵四";
stu1.age = 20;
stu1.height = 188;
stu1.sex = '男';
stu1.print();
System.out.println("--------------------------------------------");
// 分析:以上创建对象 通过 对象名给属性一个一个赋值 每一个属性单独写一行
// 能不能统一给属性赋值?可以的 通过有参构造方法
Student stu2 = new Student("广坤", 20, 175, '男');
stu2.print();
}
}
1.3 构造方法重载
构造方法重载:同一个类中的构造方法,参数列表不同
package com.atguigu.test1;
/**
* 构造方法:类中的特殊方法,主要用于创建对象
* 特点:
* 名称与类名完全相同
* 没有返回值类型。
* 创建对象时,触发构造方法的调用,不可通过句点手动调用。
*
* 注意:如果没有在类中显示定义构造方法,则编译器默认提供无参构造方法。
*
* 构造方法重载:同一个类中的构造方法,参数列表不同
* 实际开发中,每个类通常书写两个构造方法:一个无参构造,一个全参构造
* */
public class Student {
String name;
int age;
double height;
char sex;
public void print(){
System.out.println("学生的名字是:" + name + ",年龄是:" + age);
System.out.println("身高是:" + height + ",性别是:" + sex);
}
// 无参构造器
public Student(){
System.out.println("Student类无参构造执行了");
}
// 有参构造器 一个参数
public Student(String n){
name = n;
}
// 有参构造器 两个参数
public Student(String n, int a){
name = n;
age = a;
}
// 有参构造器 三个参数
public Student(String n, int a, double h){
name = n;
age = a;
height = h;
}
// 有参构造器 全部参数
public Student(String n, int a, double h, char s){
name = n;
age = a;
height = h;
sex = s;
}
public static void main(String[] args) {
Student stu1 = new Student();
stu1.name = "张三";
stu1.age = 20;
stu1.height = 178;
stu1.sex = '男';
stu1.print();
System.out.println("-----------------------");
// 分析:以上创建对象 通过对象名给属性一个一个赋值 每一个属性单独写一行 过于繁琐
// 能不能统一给属性赋值? 可以的 通过有参构造方法
Student stu2 = new Student("李四", 20, 175, '男');
stu2.print();
System.out.println("-----------------------");
Student stu3 = new Student("王五");
stu3.age = 25;
stu3.height = 173;
stu3.sex = '女';
stu3.print();
}
}
2. this关键字
this关键字:this表示当前对象 可以用于访问(当前正在使用哪个对象,this就表示哪个对象)
属性 通过this.属性名访问
方法 通过this.方法名访问
构造方法 通过this(参数) 访问 访问本类构造方法 必须在本类构造的第一句
2.1 访问属性
属性 通过this.属性名访问
package com.atguigu.test2;
/**
* 注意:如果没有在类中显示定义构造方法,则编译器默认提供无参构造方法。
* 如果书写了有参构造方法,无参构造将被覆盖,如需使用,必须显式书写。
*
* this关键字:this表示当前对象 可以用于访问
* 属性 通过this.属性名访问
* 方法 通过this.方法名访问
* 构造方法 通过this(参数) 访问 访问本类构造方法 必须在本类构造的第一句
*/
public class Student {
String name;
int age;
double height;
char sex;
public Student(){
}
public Student(String name){
this.name = name;
}
public Student(int age){
this.age = age;
}
public Student(String name,int age){
this.name = name;
this.age = age;
}
public Student(String name,int age,double height,char sex){
this.name = name;
this.age = age;
this.height = height;
this.sex = sex;
}
public static void main(String[] args) {
Student stu1 = new Student();
System.out.println("-------------------------------------------");
Student stu2 = new Student("赵四");
System.out.println("-------------------------------------------");
Student stu3 = new Student("大拿", 20, 188, '男');
System.out.println("-------------------------------------------");
Student stu4 = new Student("小宝", 20);
}
}
2.2 访问方法
通过this.方法名访问
package com.atguigu.test2;
/**
* 注意:如果没有在类中显示定义构造方法,则编译器默认提供无参构造方法。
* 如果书写了有参构造方法,无参构造将被覆盖,如需使用,必须显式书写。
*
* this关键字:this表示当前对象 可以用于访问
* 属性 通过this.属性名访问
* 方法 通过this.方法名访问
* 构造方法 通过this(参数) 访问 访问本类构造方法 必须在本类构造的第一句
*/
public class Student {
String name;
int age;
double height;
char sex;
public void printName(){
System.out.println("学生的名字是:" + name);
}
public void printAge(){
System.out.println("学生的年龄是:" + age);
}
public void print(){
this.printName();
printAge();
System.out.println("身高是:" + height + ",性别是:" + sex);
}
public static void main(String[] args) {
Student stu1 = new Student();
stu1.print();
}
}
2.3 访问构造方法
构造方法 通过this(参数) 访问 访问本类构造方法 必须在本类构造的第一句
package com.atguigu.test2;
/**
* 注意:如果没有在类中显示定义构造方法,则编译器默认提供无参构造方法,
* 如果书写了有参构造器方法,无参构造将被覆盖,如需使用,必须显示书写。
*
* this关键字:this表示当前对象 可以用于访问
* 属性 通过this.属性名访问
* 方法 通过this.关键字访问
* 构造方法 通过this(参数)访问 访问本类构造方法 必须在本类构造的第一句
* */
public class Student {
String name;
int age;
double height;
char sex;
public Student(){
}
public Student(String name){
this.name = name;
}
public Student(int age){
this.age = age;
}
public Student(String name, int age){
// this.name = name;
this(name);
this.age = age;
}
public Student(String name, int age, double height, char sex){
// this.name = name;
// this.age = age;
this(name, age);
this.height = height;
this.sex = sex;
}
public void printName(){
System.out.println("学生的名字是:" + name);
}
public void printAge(){
System.out.println("学生的年龄是:" + age);
}
public void print(){
this.printName();
this.printAge();
System.out.println("身高是:" + height + ", 性别是:" + sex);
}
public static void main(String[] args) {
Student stu1 = new Student();
System.out.println("-----------------------");
Student stu2 = new Student("赵四");
stu2.print();
System.out.println("-----------------------");
Student stu3 = new Student("大拿", 20, 184, '女');
stu3.print();
System.out.println("-----------------------");
Student stu4 = new Student("小宝", 20);
stu4.print();
}
}
封装和继承
1. 封装
访问:包括赋值和取值
封装:将类的信息隐藏在类的内部,不允许外部程序直接访问,而是通过公开的方法实现对属性的访问
具体步骤:
1.属性私有 将属性使用private修饰 被private修饰的属性表示只能在本类中访问 其他类不能访问
2.方法公开 针对每一个属性编写两个方法 分别用于属性的 赋值setter() 和 取值getter()
package com.atguigu.test3;
/**
* 企鹅类
*
* 访问:包括赋值和取值
* 封装:将类的信息隐藏在类的内部,不允许外部程序直接访问,而是哦通过公开的方法实现对属性的访问
*
* 具体步骤:
* 1.属性私有 将属性使用private修饰 被private修饰的属性表示只能在本类中访问 其他类不能访问
* 2.方法公开 针对每一个属性编写两个方法 分别用于属性的 赋值setter() 和 取值getter()
* */
public class Penguin {
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
private int health;
public void setHealth(int health){
if (health >= 0 && health <= 100){
this.health = health;
}else{
System.out.println("健康值赋值不合理,将使用默认值:60");
this.health = 60;
}
}
public int getHealth(){
return health;
}
private int love;
public void setLove(int love){
if (love >= 0 && love <= 100){
this.love = love;
}else {
System.out.println("亲密值赋值不合理,将使用默认值:60");
this.love = 60;
}
}
public int getLove(){
return love;
}
private char sex;
public void setSex(char sex){
if (sex == '雌' && sex == '雄'){
this.sex = sex;
}else{
System.out.println("性别赋值不合理,将使用默认值:雌");
this.sex = '雌';
}
}
public char getSex(){
return sex;
}
public Penguin(){
}
public Penguin(String name, int health, int love, char sex){
this.setName(name);
this.setHealth(health);
this.setLove(love);
this.setSex(sex);
}
public static void main(String[] args) {
Penguin p1 = new Penguin();
p1.name = "大白";
p1.health = -200;
p1.love = -999;
p1.sex = '男';
System.out.println(p1.name);
System.out.println(p1.health);
System.out.println(p1.love);
System.out.println(p1.sex);
}
}
package com.atguigu.test3;
public class TestPenguin {
public static void main(String[] args) {
Penguin p1 = new Penguin();
// 属性私有化之后,在其他类中无法通过对象.属性设置
// p1.name = "大白";
// p1.health = -200;
// p1.love = -999;
// p1.sex = '男';
p1.setName("大白");
p1.setHealth(-200);
p1.setLove(-999);
p1.setSex('男');
System.out.println("-----------------------");
// 属性私有化之后,在其他类中无法通过对象.属性获取
// System.out.println(p1.name);
// System.out.println(p1.health);
// System.out.println(p1.love);
// System.out.println(p1.sex);
System.out.println(p1.getName());
System.out.println(p1.getHealth());
System.out.println(p1.getLove());
System.out.println(p1.getSex());
}
}
2.封装的好处
便于使用者正确使用系统,防止错误修改属性
降低了构建大型系统的风险
提高程序的可重用性
降低程序之间的耦合度
3. 访问权限修饰符
3.1 类的访问权限修饰符
类的访问权限修饰符:
public :本项目中任何位置都可以访问
默认不写:只能在同包中访问
3.2 类成员的访问权限修饰符

类成员的访问权限修饰符:类的成员包括类中的属性、方法、构造方法
private:只能在本类中访问
默认不写:本类以及本包中可以访问
protected:本类,本包以及不再同包的子类中可以访问
public:任何位置
package com.atguigu.test6;
/**
* 类成员的访问权限修饰符:类的成员包括类中的属性、方法、构造方法
* private: 只能在本类中访问
* 默认不写: 本类以及本包中可以访问
* protected: 本类、本包以及不在同包的子类中可以访问
* public: 任何位置都可以访问
* */
public class C {
private String field1;
String field2;
protected String field3;
public String field4;
private void method1(){
System.out.println("private权限修饰的方法");
}
void method2(){
System.out.println("默认权限修饰的方法");
}
protected void method3(){
System.out.println("protected权限修饰的方法");
}
public void method4(){
System.out.println("public权限修饰的方法");
}
public static void main(String[] args) {
C c = new C();
System.out.println(c.field1);
System.out.println(c.field2);
System.out.println(c.field3);
System.out.println(c.field4);
c.method1(); // private权限修饰的方法
c.method2(); // 默认权限修饰的方法
c.method3(); // protected权限修饰的方法
c.method4(); // public权限修饰的方法
}
}
package com.atguigu.test6;
public class TestC {
public static void main(String[] args) {
C c = new C();
// System.out.println(c.field1); // 在其他类中无法访问private权限的属性
System.out.println(c.field2);
System.out.println(c.field3);
System.out.println(c.field4);
// c.method1(); // 在其它类中无法访问private权限的方法
c.method2();
c.method3();
c.method4();
}
}
package com.atguigu.test7;
/**
* 在不同包的类中只能访问public权限的属性和方法
* */
import com.atguigu.test6.C;
public class TestC {
public static void main(String[] args) {
C c = new C();
System.out.println(c.field4);
c.method4();
}
}
3.3 包问题补充
在同一个类中使用两个同名不同包的类。可以使用包名+类名
(全限定名)来访问具体指定的类。
package com.atguigu.test10;
import com.atguigu.test8.D;
public class TestD {
public static void main(String[] args) {
D d = new D();
d.m1(); // test8包中的D类 m1方法
com.atguigu.test9.D d1 = new com.atguigu.test9.D(); // 包名 + 类名来访问
d1.m1(); // test9包中的D类 m1方法
}
}
4. 继承
子类继承父类,子类与父类是is-a的关系 子类是父类 举例:狗是宠物 企鹅是宠物 笔记本电脑是电脑
父类中书写子类共有的信息(属性)和行为(方法)
子类中书写独有的信息(属性)和行为(方法)
package com.atguigu.test11;
/**
* 宠物类 父类:父类中书写子类共有的信息(属性)和行为(方法)
* */
public class Pet {
private String name;
private int health;
private int love;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getHealth(){
return health;
}
public void setHealth(int health){
this.health = health;
}
public int getLove(){
return love;
}
public void setLove(int love){
this.love = love;
}
public void print(){
System.out.println("宠物的名字是:" + name + ", 健康信息是:" + health);
System.out.println("亲密值是:" + love);
}
}
package com.atguigu.test11;
/**
* 狗狗类
* 名字
* 健康值
* 亲密值
* 品种
*
* print() 用于打印狗狗信息
*
* Dog() 无参构造器
* */
public class Dog extends Pet{
private String strain;
public String getStrain(){
return strain;
}
public void setStrain(String strain){
this.strain = strain;
}
public Dog(){}
}
package com.atguigu.test11;
/**
* 企鹅类
* 名字
* 健康值
* 亲密值
* 性别
*
* print() 打印企鹅信息
* Penguin() 无参构造方法
* */
public class Penguin extends Pet{
private String sex;
public String getSex(){
return sex;
}
public void setSex(String sex){
this.sex = sex;
}
public Penguin(){}
}
package com.atguigu.test11;
import com.atguigu.test8.D;
public class TestPet {
public static void main(String[] args) {
Dog dog1 = new Dog();
dog1.setName("大黄");
dog1.setHealth(100);
dog1.setLove(100);
dog1.setStrain("二哈");
dog1.print();
System.out.println("-----------------------");
Penguin p1 = new Penguin();
p1.setName("大白");
p1.setHealth(98);
p1.setLove(90);
p1.setSex("雌性");
p1.print();
}
}
5.super关键字
super关键字表示父类对象 可以访问父类的属性、方法、构造方法
5.1 super访问父类属性
属性:super.属性名即可访问
package com.atguigu.test12;
/**
* 宠物类 父类: 父类中书写子类共有的信息(属性)和行为(方法)
* */
public class Pet {
protected String name;
protected int health;
protected int love;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getHealth(){
return health;
}
public void setHealth(int health){
this.health = health;
}
public int getLove(){
return love;
}
public void setLove(int love){
this.love = love;
}
public void print(){
System.out.println("宠物的名字是:" + name + ", 健康值是:" + health);
System.out.println("亲密值是:" + love);
}
}
package com.atguigu.test12;
public class Dog extends Pet{
private String strain;
public String getStrain(){
return strain;
}
public void setStrain(String strain){
this.strain = strain;
}
public Dog(){}
public Dog(String strain, String name, int health, int love){
this.strain = strain;
this.name = name;
super.health = health;
super.love = love;
}
public void printDog(){
super.print();
System.out.println("狗狗的品种是:" + strain);
}
}
package com.atguigu.test13;
import com.atguigu.test12.Pet;
public class Cat extends Pet {
private String furColor; // 毛发颜色
public String getFurColor(){
return furColor;
}
public void setFurColor(String furColor){
this.furColor = furColor;
}
public Cat(){}
public Cat(String furColor, String name, int health, int love){
this.furColor = furColor;
this.name = name;
this.health = health;
this.love = love;
}
public void printCat(){
super.print();
System.out.println("猫咪的颜色是:" + furColor);
}
}
package com.atguigu.test12;
import com.atguigu.test13.Cat;
/**
* super关键字表示父类对象 可以访问父类的属性、方法、构造方法
* 属性:super.属性名即可访问
* 方法:super.方法名即可访问
*
* super关键字访问父类构造方法:
* 1.子类的构造默认访问父类的无参构造
* 2.除非子类显示访问父类的有参构造方法
* 子类构造必然访问父类的有参或者无参构造中的其中一个
* */
public class TestPet {
public static void main(String[] args) {
Dog dog = new Dog("金毛", "小金", 100, 100);
dog.print();
System.out.println("-----------------------");
dog.printDog();
System.out.println("-----------------------");
Cat cat = new Cat("绿色", "花花", 80, 80);
cat.print();
System.out.println("-----------------------");
cat.printCat();
}
}
5.2 super访问父类方法
方法:super.方法名即可访问
package com.atguigu.test12;
/**
* 宠物类 父类: 父类中书写子类共有的信息(属性)和行为(方法)
* */
public class Pet {
protected String name;
protected int health;
protected int love;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getHealth(){
return health;
}
public void setHealth(int health){
this.health = health;
}
public int getLove(){
return love;
}
public void setLove(int love){
this.love = love;
}
public void print(){
System.out.println("宠物的名字是:" + name + ", 健康值是:" + health);
System.out.println("亲密值是:" + love);
}
}
package com.atguigu.test12;
public class Dog extends Pet{
private String strain;
public String getStrain(){
return strain;
}
public void setStrain(String strain){
this.strain = strain;
}
public Dog(){}
public Dog(String strain, String name, int health, int love){
this.strain = strain;
this.name = name;
super.health = health;
super.love = love;
}
public void printDog(){
super.print();
System.out.println("狗狗的品种是:" + strain);
}
}
package com.atguigu.test13;
import com.atguigu.test12.Pet;
public class Cat extends Pet {
private String furColor; // 毛发颜色
public String getFurColor(){
return furColor;
}
public void setFurColor(String furColor){
this.furColor = furColor;
}
public Cat(){}
public Cat(String furColor, String name, int health, int love){
this.furColor = furColor;
this.name = name;
this.health = health;
this.love = love;
}
public void printCat(){
super.print();
System.out.println("猫咪的颜色是:" + furColor);
}
}
package com.atguigu.test12;
import com.atguigu.test13.Cat;
/**
* super关键字表示父类对象 可以访问父类的属性、方法、构造方法
* 属性:super.属性名即可访问
* 方法:super.方法名即可访问
*
* super关键字访问父类构造方法:
* 1.子类的构造默认访问父类的无参构造
* 2.除非子类显示访问父类的有参构造方法
* 子类构造必然访问父类的有参或者无参构造中的其中一个
* */
public class TestPet {
public static void main(String[] args) {
Dog dog = new Dog("金毛", "小金", 100, 100);
dog.print();
System.out.println("-----------------------");
dog.printDog();
System.out.println("-----------------------");
Cat cat = new Cat("绿色", "花花", 80, 80);
cat.print();
System.out.println("-----------------------");
cat.printCat();
}
}
5.3 super访问父类构造方法
super关键字访问父类构造方法:
1.子类构造默认访问父类的无参构造
2.除非子类构造显式访问父类的有参构造方法
子类构造必须访问父类的有参或者无参构造其中一个
package com.atguigu.test14;
public class Dog extends Pet{
private String strain;
public String getStrain(){
return strain;
}
public void setStrain(){
this.strain = strain;
}
public Dog(){
System.out.println("子类Dog类中的无参构造方法执行了");
}
public Dog(String strain, String name, int health, int love){
super(name, health, love);
this.strain = strain;
}
public void printDog(){
super.print();
System.out.println("狗狗的品种是:" + strain);
}
}
package com.atguigu.test14;
public class Penguin extends Pet{
private String sex;
public String getSex(){
return sex;
}
public void setSex(String sex){
this.sex = sex;
}
public Penguin(){
System.out.println("子类Penguin类中的无参构造方法执行了");
}
public Penguin(String sex, String name, int health, int love){
super(name, health, love);
this.sex = sex;
}
public void printPenguin(){
super.print();
System.out.println("企鹅的性别是:" + sex);
}
}
package com.atguigu.test14;
public class Pet {
protected String name;
protected int health;
protected int love;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getHealth(){
return health;
}
public void setHealth(int health){
this.health = health;
}
public int getLove(){
return love;
}
public void setLove(int love){
this.love = love;
}
public void print(){
System.out.println("宠物的名字是:" + name + ", 健康值是:" + health);
System.out.println("亲密值是:" + love);
}
public Pet(){
System.out.println("父类Pet类的无参构造方法执行了");
}
public Pet(String name, int health, int love){
this.name = name;
this.health = health;
this.love = love;
}
}
package com.atguigu.test14;
public class TestPet {
public static void main(String[] args){
Dog dog = new Dog();
System.out.println("---------------------------");
Penguin p1 = new Penguin();
System.out.println("---------------------------");
Dog dog1 = new Dog("拉布拉多", "大黄", 100, 100);
dog1.printDog();
System.out.println("---------------------------");
Penguin p2 = new Penguin("雌性", "大白", 80, 90);
p2.printPenguin();
}
}

被折叠的 条评论
为什么被折叠?



