Java SE 基础(八)Java面向对象三/四大特征

Java SE 基础(八)Java面向对象三/四大特征

封装

  • 面向对象三大特征:封装、继承、多态
  • 面向对象四大特征:封装、继承、多态、抽象
  • 为了防止随意给对象属性赋值可能存在的隐患,我们可以将属性进行封装,封装到类的内部,外部就无法直接访问属性,必须通过类提供的方法来访问。
  • 封装的步骤:
  1. 修改属性的访问权限;
  2. 提供外部代码可以直接调用的方法完成赋值;
  3. 在setter方法中加入属性的逻辑控制,确保数值的正确性;
public class Student { 
	private int age; 
	private String name; 
	private char gender; 
	private String password; 
	public void setAge(int age){ 
		if(age <= 0){ 
			System.out.println("年龄不合法!已经赋予默认值 3"); 
			this.age = 3; 
		}else{
			this.age = age; 
		} 
	}

	public void setName(String name) { 
		this.name = name; 
	}

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

	public void setPassword(String password) {
		this.password = password; 
	}
	
	public void show(){ 
		System.out.println("用户信息如下"); 
		System.out.println("年龄" + this.age); 
		System.out.println("用户姓名" + this.name); 
		System.out.println("用户性别" + this.gender); 
		System.out.println("用户密码" + this.password); 
	} 
}

public class Text { 
	public static void main(String[] args) { 
		Student student = new Student(); 
		student.setAge(8); 
		student.setName("张三"); 
		student.setGender('男'); 
		student.setPassword("123123"); 
		student.show(); } }

static

  • static表示静态或全局,可以用来修饰成员变量、成员方法以及代码块;
    类中成员变量/方法(非静态)需要访问时,必须依赖于对象(外部访问)
public class User { 
	//成员变量 
	public int id; 
	//成员方法 
	public void test(){ 
		System.out.println(id); 
	} 
}

public class Test { 
	public static void main(String[] args) { 
		User user = new User(); 
		user.id = 100; 
		user.test(); 
	} 
}
  • 使用static修饰成员变量/成员方法时,该对象或方法就会独立于该类的任何一个实例对象,访问时就不需要依赖于对象;
public class User { 
	//静态成员变量 
	public static int id; 
	//静态成员方法 
	public static void test(){ 
		System.out.println(id); 
	} 
}


public class Test { 
	public static void main(String[] args) { 
		User.id = 2; 
		User.test(); 
	} 
}
  • 总结:
  1. 非静态成员不属于类,属于每个实例化对象。每个实例化对象都有自己的成员变量,彼此独立,互不影响;
  2. 静态成员变量属于类,不属于实例化对象。只不过实例化对象可以引用类中的成员变量,由此大家共享。只要一个对象修改成员变量,所有的对象引用全部修改;
  3. 使用static修饰成员变量时需要注意,静态方法中不能使用this关键字,不能直接访问所属类的实例变量和实例方法;
  4. 静态方法中不能访问非静态变量,但在非静态方法中可以访问静态变量;
  5. static除了可以修饰成员变量和成员方法外还可以修饰代码块,被其修饰了的代码块叫做静态代码块;
  • 类中的代码块什么时候执行?
    当Java程序加载该类时执行,每当Java程序中出现该类的时候,就会执行一次;

  • 静态代码块什么时候执行?
    当Java程序第一次加载该类的时候执行,当Java程序中第一次出现该类的时候执行一次,后面再出现该类就不再执行;

继承

  1. 继承描述的是类与类之间的一种关系,将类分为父类和子类,子类可以直接获取父类中的所有公有(public)资源(成员变量和方法),是Java 程序提高代码复用性的一种重要方式。
  2. 一个子类只能有一个直接父类,但是可以有多个间接父类(父类也可以有父类)。
  • 之类访问父类
    实现了继承关系的父子类,在创建子类对象的时候,会优先创建父类对象,无论子类是通过有参构造还是无参构造来创建对象,父类都是通过无参构造来创建。
    子类的成员方法中可以通过 super 关键字调用父类的成员变量和成员方法。
public class Teacher extends People { 
	public Teacher(){ 
		super(1); 
		System.out.println("调用了Teacher的无参构造"); }


	public Teacher(int i){ 
		super(1); 
		System.out.println("调用了Teacher的有参构造"); 
	} 
}

People 有没有父类?
有,每个 Java 类都会有一个默认的父类 Object,Object 是所有 Java类的根节点,Java 中的所有类(无论是官方 JDK 提供的类还是开发者自定义的类,第三方框架定义的类)都是 Object 的后代(直接子类或者间接子类)

默认父类是通过无参来创建对象的,如何让父类通过有参来创建的?
需要使用 super 关键字,this 用作访问当前类的属性和方法,super用作访问父类的属性和方法。

子类访问权限

访问权限修饰符:public、private、protected、默认(不写)

权限修饰符同一类同一包不同包子类
public可以访问可以访问可以访问可以访问
protected可以访问可以访问不能访问可以访问
默认可以访问可以访问不能访问可以访问(同包)
private可以访问不能访问不能访问不能访问
  • Java 中的包是用来管理文件的,一共系统中类非常多,不可避免会出现类名重复的情况,通过设置包的方式来解决这一问题,同一个包中不能出现相同的类名,但是在不同的包中可以出现相同的类名。
  • 包的命名规范:包名由小写字母组成,不能以.开头或者结尾,可以包含数字,但是不能以数字开头,如果以数字开头则不是一个包,只是一个文件夹,不能创建 Java 代码。
  • 一般命名的话以组织的网络域名方向输出就是包名。

方法重写

  • 建立在继承的基础上,子类对父类方法的重新定义并覆盖的操作叫做重写;
  • 构造方法不能被重写,方法重写规则:
  1. 父之类方法名相同;
  2. 父之类的方法参数列表相同;
  3. 子类返回值与父类返回值类型相同或是其子类;
  4. 子类方法的访问权限不能小于父类;
  • 访问全县按照作用域从大到小:

    • public>protected>默认>private
    • 如果父类访问权限为 public,那么子类只能是 public如果父类访问权限为 protected,那么子类可以是public、protected如果父类访问权限为默认,那么子类可以是 public、protected、默认;
    • 重写必须建立在继承的基础上,子类只能继承父类的非私有的方法和属性,也就是说父类私有的方法子类压根不能继承,那么也就不存在重写了。
  • 方法重写对比方法重载

所在位置方法名参数列表返回值访问权限
方法(覆盖)重写父之类中相同相同相同或是其子类不能小于父类
方法重载同一类中相同不能访问没有要求没有要求

多态

  • 多态的概念比较抽象,简单解释就是:一个事物在不同时间地点有不同表现形体;
  • Java程序中,就是定义一个方法,在具体的生成环境中根据不同的需求呈现出不同的业务逻辑;
  • 业务场景:书店的普通会员买书有折扣
public class Member { 
	public void buyBook(){ } 
}

public class OrdinaryMember extends Member { 
	@Override 
	public void buyBook() { 
		System.out.println("普通会员买书9折"); 
	} 
}

public class SuperMember extends Member { 
	@Override 
	public void buyBook() { 
		System.out.println("超级会员买书6折"); 
	} 
}

public class Cashier { 
	private Member member; 
	public void setMember(Member member) { 
		this.member = member; 
	}
	public void settlement(){ 
		this.member.buyBook(); 
	} 
}

public class Text { 
	public static void main(String[] args) { 
		Member member = new OrdinaryMember(); 
		Cashier cashier = new Cashier(); 
		cashier.setMember(member); 
		cashier.settlement(); 
	} 
}
  • 多态是基于继承/抽象,因为多态最核心的点就是一个事物可以有很多种不同的表现形式。一个对象可以转换为不同类的对象(数据类型的转换),也就是说必须有数据类型转换在前,才可能有多态;
  • 引用数据类型转换就是基于继承的;

多态的使用

  • 在实际开发中,多态主要有两种表现形式:
  1. 一种是定义方法时形参为父类,调用方法时传入参数为子类对象;
public class Cashier { 
	public void settlement(Member member){ 
		member.buyBook(); 
	} 
}

public class Text { 
	public static void main(String[] args) { 
		Cashier cashier = new Cashier(); 
		OrdinaryMember ordinaryMember = new OrdinaryMember(); 
		cashier.settlement(ordinaryMember); 
		SuperMember superMember = new SuperMember(); 
		cashier.settlement(superMember); } }
  1. 另一种是定义方法时返回值类型为父类,调用方法时返回值为子类对象;
public Member getMember(String name){ 
	if(name.equals("ordinaryMember")){ 
		return new OrdinaryMember(); 
	}
	if(name.equals("superMember")){ 
		return new SuperMember(); 
	}
	return null; 
}

Cashier cashier = new Cashier(); 
System.out.println(cashier.getMember("ordinaryMember"));
System.out.println(cashier.getMember("superMember"));

Member member = new OrdinaryMember(); 
OrdinaryMember member1 = (OrdinaryMember) new Member();
  • 父类引用可以直接指向子类,子类转父类可以自动完成,无需强制转换。向上转型;
  • 子类应用不能直接指向父类,父类专子类需要强制完成。向下转型;

抽象

  • 如果一个方法没有具体的方法实现(方法体),只有方法的定义,那么这个方法就叫做抽象方法,声明抽象方法时需要添加 abstract 关键字;
  • 一旦类种定义了抽象方法,则该类也必须声明为抽象类,需要在类定义处添加 abstract 关键字;
public abstract class Member{
	public abstract void buyBook();
}
  • 抽象类和普通类的区别就是抽象类不能被实例化,抽象方法和普通方法的区别时抽象方法没有方法体;
  • 抽象类中可以没有抽象方法;
public abstract class Member { 
	public void test(){
		
	} 
}
  • 但是包含了抽象方法的类一定是抽象类;
public abstract class Member { 
	public abstract void buyBook(); 
}
  • 可以在抽象类中定义普通方法,但是不能在普通类中定义抽象方法。继承了抽象类的子类必须要重写父类的抽象方法,完成方法的具体实现;
public class OrdinaryMember extends Member { 
	@Override 
	public void buyBook() { 
		System.out.println("9折"); 
	} 
}
  • 如果子类也是抽象类,可以不用重写父类抽象方法;
public abstract class OrdinaryMember extends Member { 

}
  • 匿名内部类:匿名内部类就是一个重写了父类抽象方法的子类,只不过我们将它定义在了方法内部,并且没有名字。所以叫匿名内部类;
public class Test { 
	public static void main(String[] args) { 
		Member member = new Member() { 
			@Override 
			public void buyBook() { 
				System.out.println("3折"); 
			}
		}; 
	} 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值