关于java面向对象概念的理解及知识点(三)

面向对象的三大特征

1.封装
封装
 隐藏实现细节,对外只提供公共访问的访问方式;
 
在java中封装的体现:
 1)方法:
   对方法的实现不用考虑其怎么实现的,只要告知了我们方法的名称 参数类型
   作用和返回值类型,这个方法我们就能使用;
 2)对象:
   对象就封装了数据和功能,只要拿到这个对象,就能使用这个对象的数据个和功能了;
 3)私有化类的成员属性,对外给属性提供公共的getXxx/setXxx方法去间接的给属性
   取值和赋值;
   怎么取值怎么赋值不是我们关心的,我们只关系get方法可以取到值,set方法可以赋值
   就可以了;
1.1. 类成员的访问控制
对于类的成员(属性、方法)的访问控制,四种修饰符都可以使用
每种权限修饰的成员的使用范围见图

在这里插入图片描述

类:
默认,public,final,abstract
我们自己定义:public居多

成员变量:
四种权限修饰符均可,final,static
我们自己定义:private居多

构造方法:
四种权限修饰符均可,其他不可
我们自己定义:public 居多
		
成员方法:
四种权限修饰符均可,fianl,static,abstract
我们自己定义:public居多

代码如下:

public class Demo4 
{
   
   public static void main(String[] args){
       /*
	   Employee emp1 =  new Employee();
	   emp1.name = "jack";
	   emp1.age = -10;
	   
	   //jack -10 程序的执行没有问题,而是程序不符合生活逻辑问题;
	   emp1.show();

	   System.out.println("=======================");
       */
	   
       
	   /*
	   //判断处理
	   int age = -10;
	   if(age>=0 && age<=120){//合法年龄
		   emp1.age = age;
	   }else{//非法年龄
 	       emp1.age = 0;
	   }

	   emp1.show();

	   System.out.println("----------------------");

	   Employee emp2 = new Employee();
	   emp2.name = "rose";
       
	   //判断处理
	   age = -20;
	   if(age>=0 && age<=120){
	     emp2.age = age;
	   }else{
	     emp2.age = 0;
	   }

	   emp2.show();
	   //代码复用性问题

	   System.out.println("-----------------------");
       */

	   Employee emp3 = new Employee();
	   emp3.name = "smith";
	   emp3.setAge(-20);

	   emp3.show();
        
	   //emp3.age = -20;
       //emp3.show();

	   //如果使用员工对象的封装方法setAge()去给员工的age属性赋值,就能对员工年龄进行逻辑
	   //判断再赋值的效果;但是仍然可以使用 对象.属性 的方式给员工的age属性赋值呀,那么问题
	   //又回到一开始的问题了;

	   //问题是:只能去使用员工对象的setAge()方法进行逻辑判断并给age属性赋值,而不让使用 
	   //对象.属性 的方式去给员工对象的age属性赋值;

	   emp3.setAge(22);
	   emp3.show();

	   System.out.println("-----------------------------");

	   Student s = new Student();
	   s.setSno(101);
	   s.setName("jack");
	   s.setAge(21);
       s.show();
	   System.out.println(s.getSno()+"  "+s.getName()+"   "+s.getAge());
   }
}

//员工描述类
class Employee
{
	//成员属性
    String name;

	private int age;

	//成员方法 
	public void show(){
	  System.out.println(name+"   "+age);
	}

	/*
	 对年龄的判断进行了一个方法的封装,就能提高代码复用性了,同时
	 将这个方法给定成了员工的功能方法,即就是只要是个员工(对象)都
	 具有该功能;
	*/
	public void setAge(int a){
	   if(a>=0 && a<=120){
	     age = a;
	   }else{
	     age = 0;
	   }
	}
}

class Student
{
	//成员属性
	private int sno;

	private String name;

	private int age;

	//get/set
	public void setSno(int no){
	  sno = no;
	}
	public int getSno(){
	  return sno;
	}
    public void setName(String n){
	  name = n;
	}
	public String getName(){
	  return name;
	}
	public void setAge(int a){
	  age = a;
	}
	public int getAge(){
	  return age;
	}
	//成员方法
	public void show(){
	  System.out.println(sno+"   "+name+"   "+age);
	  System.out.println(getSno()+"   "+getName()+"   "+getAge());
	}
}
2.继承
	继承
	当多个类有共同的属性和方法时,可以抽取出一个父类
	继承的主要作用就是为了实现代码的复用,简化编写
	
	注意:并不是所有的有共同属性和方法的类都可以使用继承,使用继承必须要满足一个is a
	的关系
	
	关键字:
	extends 
	被继承的类叫父类 继承的类叫子类
	
	1.子类继承父类的,可以将父类中所有的非私有内容继承过来
	2.子类中还可以有自己的特有属性和方法
	3.子类还可以重写父类的中的方法
	什么时候子类需要重写父类中的方法
		父类的方法不能满足子类的需求的时候

	4.构造方法不能被继承
	5.java中,类与类之间是单继承
	6.java中所有的类都直接或间接的继承object类
		如果指明了父类,间接的继承object类
		如果没有指明父类,默认直接的继承object类
2.1 this关键字和super关键字
	this:当前对象的使用
	1.使用this区分成员变量和局部变量
	2.在方法中使用this调用本类的其他方法
	3.在构造方法中调用本类中调用本类的其他构造方法
		
    super:父类对象引用
	1.super可以调用父类的成员变量和方法
	2.super在构造方法中调用父类的构造方法
	
	在一个构造方法中,super()和this()不能共存
	
	构造方法的特殊性:
		当创建子类对象调用子类的对象的构造方法,会默认调用父类的无参构造方法
		
		我们无法控制构造方法的执行顺序,总是先执行辈分大的类的构造方法
		
   Super和this的区别
	1.	this在方法中调用本类的其他方法,super在方法中调用父类的方法
	2.	在构造方法中,this可以在构造方法中去调用本类的其他构造方法,super在构造方法中调用父类的构造方法
	3.	This和super构造方法中使用的时候都必须放在构造方法代码的第一行
2.2 final修饰符
	final可以修饰类、变量、方法
	
	final修饰的类叫最终类,最终类不能被继承
			String类就是最终类 不能被继承
	final修饰变量,变为常量,只能被赋值一次
	
	赋值要在创建对象之前赋值
	赋值的时机:
		1.声明常量的时候直接赋值
		2.构造方法内赋值
		3.可以在构造代码块中赋值
		4.如果是静态常量还可以可以在静态代码块中赋值
		
	final修饰的方法不能被重写
	final修饰形参,形参值不能被改变
		形参可以被使用,但是不能改变形参的值
		
	instanceof 比较关键字
	判断一个对象是不是一个类的对象

代码如下:
animal类

public class Animal {

	private String name;
	private int age;
	private String sex;
	
	public Animal() {
		
	}
	
	public Animal(String name) {
		this.name = name;
	}

	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 getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public void eat(){
		System.out.println(".....吃草");
	}
	
	public void sleep(){
		System.out.println("....睡");
	}
	
}

cat类

//Cat继承Animal
public class Cat extends Animal {

	public void climb(){
		System.out.println("....猫爬树");
	}
	
	//重写父类的eat方法
	public void eat(){
		System.out.println("....猫吃鱼");
	}
}

dog类

//Dog继承Animal
public class Dog extends Animal {

	public void look(){
		System.out.println("...狗看门");
	}
	
	//重写父类的eat方法
	public void eat(){
		System.out.println("....狗吃骨头");
	}
}

测试类

public class Test {

	public static void main(String[] args) {
		//创建一个Cat的对象
		/*Cat c=new Cat();
		c.eat();
		c.sleep();
		c.setName("花花");
		String name=c.getName();
		System.out.println(name);
		c.climb();
		
		//创建一个Dog对象
		Dog d=new Dog();
		d.sleep();
		d.look();*/
		
		//instanceof  判断一个对象是不是一个类的对象
		Cat c=new Cat();
		Dog d=new Dog();
		System.out.println(c instanceof Cat);//判断对象c是不是Cat类的对象
		//System.out.println(c instanceof Dog);//编译报错
		System.out.println(c instanceof Animal);
		
		Animal a=new Animal();
		System.out.println(a instanceof Cat);//false
		
		
	}
}
3.多态
多态:
	一个事物(对象)在不同的情况下可以有不同的形态
实现多态的前提:
	1.要有继承关系
	2.要有子类去重写父类的方法
				如果没有也可以,但是没有方法重写的多态是没有意义的
	3.要有父类引用指向子类对象
	
多态的特点:
		父类指向子类的对象
			1.通过父类引用调用子类对象重写后的方法时,调用的是子类
			重写后的方法
			2.父类引用不能调用子类对象特有的方法
					动态绑定
					Animal a = new Cat();
					在编译期,对于一个引用并不能确定它的具体类型,在运行期才能具体确定
					它的具体类型
			3.如果非要调用子类特有的方法
			向上转型
				将子类类型转换为父类类型----自动转换
				子----父
			向下转型
				将父类类型转换为子类类型-----强制转换
				目标类型 名 = (目标类型)引用;
				编译看左边,执行看右边
				
只有普通方法具有多态性
final、static、private方法不具有多态性
成员变量,不具有多态性

表面上的内容它不具有多态性,实际的行为才具有多态性

多态的作用:
1.提高了程序的维护性(由继承保证)
2.提高了程序的扩展性(由多态保证)

增强for循环------for-each循环
增强for循环主要是为了 为了遍历数组或者集合中的元素
for(遍历的单个元素的数据类型 存放单个元素的变量:要遍历的集合或者是数组){
	循环体
}

多态的缺点:
	父类的引用不能调用子类的特有的方法
	
抽象:
	abstract
	抽象类 用abstract修饰的类 叫抽象类
	如果一个类,没有具体的对象,可以将一个类定义为抽象类
抽象类的特点:
		1.抽象类不能实例化
		2.重选另类存在的惟一的意义就是被继承
		3.有抽象方法的类一定是抽象类,但是抽象类不一定有抽象方法
		4.抽象类中的可以有抽象方法,也可以有非抽象方法
抽象方法:
用abstract修饰的方法,方法只有方法的声明,没有方法的具体实现

抽象方法相当于一个规则,一个标准
指明了只要是这个类型,就要有这个功能

抽象类的成员特点:
	1.抽象类可以有成员变量
	2.抽象类可以有构造方法,但是不能被实例化
	3.抽象类可有抽象方法,也可以有非抽象的方法
	
abstract不能和以下的关键字共存
private冲突,final冲突,static无意义

接口:

	接口是比抽象类更抽象的东西
	1.接口中所有的方法都是抽象方法
		接口中定义的方法默认的访问修饰符 public abstract
	2.接口没有构造方法,也不能被实例化
	3.接口存在的意义就是被实现implements
	4.如果一个类要实现一个接口,就需要实现接口中的所有的方法
	5.抽象类中可以有抽象方法
	6.抽象类可以有普通的成员变量
	
	接口作用:
		接口就是一个规则,规范
		一个类实现了接口,就代表这个类遵守接口的规范
		
		有了抽象类为什么还有接口
			将抽象类中的所有方法定义成抽象方法和接口有什么区别
			
			Java中的类的继承具有很大的局限性,java中的继承只能是单继承
			一个子类只能有一个直接的父类
			类实现接口是可以多实现,也就是说一个类可以实现多个接口
			
			类和类的关系:单继承
			
			类和接口的关系;多实现
			
			接口和接口的关系:
			多继承,一个接口可以继承多个接口

代码如下:
利用上面的animal,cat,dog类,在写一个测试类

public class Test {

	public static void main(String[] args) {
		/*Cat c1=new Cat();
		Dog d1=new Dog();*/
		
		//父类引用指向子类对象
		Animal a1=new Cat();
		a1.eat();//调用的是子类重写后的方法
		a1.sleep();
		//父类引用不能调用子类特有的方法
		//a1.climb();
		
		//如果非要调用子类特有的方法,使用向下转型强制的将父类类型转换为子类类型
		Cat c=(Cat)a1;
		c.climb();
		a1.fun();
		System.out.println(a1.n);//10
		
		/*Animal a2=new Animal();
		Cat c2=(Cat)a2;*/
		
		/*Animal a3=new Dog();
		Cat c3=(Cat)a3;*/
		
		/*Cat.fun();
		Animal.fun();*/
		
		
		/*Animal a2=new Dog();
		a2.eat();
		
		Animal a3=new Animal();
		a3.eat();*/
		
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值