星期二, 十一月 10, 2015 10:34:07
封装
继承
可以从一个简单的类继承出相对复杂高级的类
多态
可以动态的对对象进行调用,使对象之间变得相对独立。
一:类的封装性
1.看下面的案例、
----1.1代码案例:
package day09;
public class CapsulationTest {
public static void main(String[] args) {
Person p = new Person();
p.age = -23;
p.name = "宇宙歆儿";
p.talk();
}
}
class Person {
String name;
int age;
Person() {
}
public void talk() {
System.out.print("我的名字叫:"+name+"\n"+"年龄:"+age);
}
}
运行结果:
我的名字叫:宇宙歆儿
年龄:-23
注意:
加工的原料有问题,生产出来的也有问题。
而导致这种错误的原因是,就是因为程序在原料的入口没有校验。
----1.2.类的封装实例
之前所列举的程序都是用对象直接访问类中的属性,这在面向对象法则中是不允许的。
所以为了避免程序中这种错误的发生,在一般的的开发中往往要将类中的属性封装(private)。
代码案例:
package day09;
public class CapsulationTest {
public static void main(String[] args) {
Person p = new Person();
p.age = -23;
p.name = "宇宙歆儿";
p.talk();
}
}
class Person {
private String name;//设置为private
private int age;//设置为private
Person() {
}
public void talk() {
System.out.print("我的名字叫:"+name+"\n"+"年龄:"+age);
}
}
结果:
p.age = -23;
p.name = "宇宙歆儿";
直接对对象的属性进行访问,出现报错。是因为设置的属性为private,不可以直接对其进行访问。
注意:
为私有的,不可以直接访问,这样就可以保证对象无法直接去访问类中的属性。
但是如果非要给对象赋值的话,解决方法是:
会增加一些方法,如 setXxx()、 getXxx()这样的公用方法来解决这一矛盾。
----1.3自己总结:
1.通过set方法进行将privat的值改变
改变完了还是private的修饰符
2.要使用get方法取出私有属性的值
然后转换为外部可访问的值。
----1.4代码案例:
package day09;
public class CapsulationTest {
public static void main(String[] args) {
Person p = new Person();
p.setName("宇宙歆儿");
p.setAge(3);
/*p.getAge();
p.getName();*/
p.talk();//这个不用调用get是因为talk()已经可以访问了
}
}
/*setXxx()、 getXxx()为了解决:
但是如果非要给对象赋值的话,解决方法是:
会增加一些方法,如 setXxx()、 getXxx()这样的公用方法来解决这一矛盾。*/
class Person {
private String name;
private int age;
Person() {
}
public void talk() {
System.out.print("我的名字叫:"+name+"\n"+"年龄:"+age);
}
public void setName(String name) {
this.name = name;
}
public void setAge(int a) {
if (a > 0) {
this.age = a;
}
}
public String getName() {
return name;
}
public int getAge () {
return age;
}
}
运行结果:
我的名字叫:宇宙歆儿
年龄:3
在set中设置了判断合理性
,设置age = -23
运行结果:
我的名字叫:宇宙歆儿
年龄:0
age为默认值0,可以保证数据的安全性。
注意:
关于封装与否并没有明确的规定,不过从程序设计的角度来说,一般来说设计较好的程序的类中的属性都是需要封装的。
此时则只能使用setXxx()、getXxx()方法,这是一个明确的标准的规定。
将属性进行私有化
----1.5封装的优点:
(1)隐藏类的实现细节;
(2)让使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作;
(3)便于修改,增强代码的可维护性;
二.类的继承
类的继承可以以既有类为基础,进而派生出新的类。
通过这种方式,便能快速地开发出新的类,
而不是编写相同的程序代码,这就是程序代码再利用的概念。
----2.1继承的基本概念
在Java中,通过继承可以简化类的定义,扩展类的功能。
在Java中支持类单继承和多继承,但是不支持多继承,
即一个类只能继承一个类而不能继承多个类。
继承的格式:
class 子类名 extends 父类
Java继承
-----只能直接继承父类中的公有属性和公有方法,
而隐含地(不可见地)继承了私有属性。
----2.2类的继承的实例
代码案例:
package day09;
public class InheritTest {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("瓦询");
s1.setAge(24);
s1.setSchool("丰趣海淘");
System.out.println(s1.getName()+"\n"+s1.getAge()+"\n"+s1.getSchool());
}
}
class Person{
private String name ;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
class Student extends Person {
private String school;
public void setSchool(String school) {
this.school = school;
}
public String getSchool() {
return school;
}
}
运行结果:
瓦询
24
丰趣海淘
注意:
在Java中只允许单继承,而不允许多重继承,也就是说一个子类只能有一个父类。
但是Java中却允许多层继承。A<--B<--C
----2.3.类的继承专题研究
关于继承的问题,有一些概念和过程需要澄清,有些语法和术语需要熟练掌握。本节做一些总结。
2.3.1子类对象的实例化过程
结论:
子类对象在实例化时会默认先去调用父类中的无参构造方法,之后再调用本类中的相应的构造方法。
代码案例:
package day09;
public class InheritTest {
public static void main(String[] args) {
Student s1 = new Student();
}
}
class Person{
String name ;
int age;
public Person() {
System.out.print("public Person()"+"\n");
}
}
class Student extends Person {
String school;
public Student() {
/*super();*/
System.out.print("public Student()");
}
}
运行结果:
public Person()
public Student()
2.3.2 super关键字
结论:
super主要的功能时完成子类调用父类中的内容,也就是调用
父类中的属性或方法。
注意:
用super调用父类中的构造方法,只能放在程序的第1行。
代码案例:
/*用super调用父类中的构造方法*/
package day09;
public class InheritTest {
public static void main(String[] args) {
Student s1 = new Student();
s1.school = "海淘";
System.out.print("姓名:"+s1.name+"\n年龄: "+s1.age+"\n学校:"+s1.school);
}
}
class Person{
String name ;
int age;
public Person(String n,int a) {
this.name = n ;
this.age = a;
}
}
class Student extends Person {
String school;
public Student() {
super("宇宙歆儿7",25);
}
}
运行结果:
姓名:宇宙歆儿7
年龄: 25
学校:海淘
super关键字不仅可用于调用父类中的构造方法,也可用于调用父类中的属性和方法。
格式:
super.父类中的属性;
super.父类中的方法()
2.3.3通过super调用父类的属性和方法
代码案例:
package day09;
public class InheritTest {
public static void main(String[] args) {
Student s1 = new Student("刘惜君",28,"恋风恋歌");
System.out.print(s1.school);
}
}
class Person{
String name ;
int age;
public Person() {
}
public String talk() {
return "...名称:"+name+"\n年龄:"+age;
}
}
/*通过super调用父类的属性和方法*/
class Student extends Person {
String school;
public Student(String name,int age,String school) {
super.name = name;//在这里使用super进行调用父类的属性
super.age = age;
System.out.println(super.talk());//调用父类中的方法
this.school = school;//调用本类中的属性
}
}
运行结果:
...名称:刘惜君
年龄:28
恋风恋歌
本例中,super换成this也是可以的,那为什么还要用super呢?
----见下例
2.3.4.限制子类的访问
有些时候,父类并不希望子类可以访问自己的类中全部的属性和方法,所以需要将一些属性与方法隐藏起来,不让子类去使用。
为此可在声明属性或方法时加上“private”关键字,表示私有。
代码案例:
package day09;
public class InheritTest {
public static void main(String[] args) {
Student s = new Student();
s.setVar();
System.out.println("名称:"+s.getName()+"\n"+s.getAge());
}
}
class Person{
private String name ;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
class Student extends Person {
public void setVar() {
super.setName("宇宙");
super.setAge(1111);
}
}
运行结果:
名称:宇宙
年龄:1111
2.3.5最后注意 super 与 this 的区别:
super 不是一个对象的引用,
不能将 super 赋值给另一个对象变量,
它只是一个指示编译器调用父类方法的特殊关键字。
super 关键字的功能:
调用父类中声明为 private 的变量。
点取已经覆盖了的方法。
作为方法名表示父类构造方法。
2.3.6代码案例:
package day09;
public class InheritTest {
public static void main(String[] args) {
Student s = new Student();
s.setVar();
}
}
class Person{
private String name = "jami soul she";
public String getName() {
return name;
}
}
class Student extends Person {
public void setVar() {
// 通过 getter 方法调用父类隐藏变量
System.out.println(super.getName());
}
}
运行结果:
jami soul she
----4.覆盖
在程序中可以看到,在子类中可以通过super.方法()调用父类中被子类覆盖的方法。
代码案例:
/*验证在遇到方法的覆盖时,可以使用super调用父类的方法 */
package day09;
public class InheritTest {
public static void main(String[] args) {
Student s = new Student("五月天",32,"五迷五迷");
System.out.print(s.talk1());
}
}
class Person{
String name ;
int age;
public String talk1() {
return "姓名="+name+"\n年龄="+age;
}
}
class Student extends Person {
String school;
public Student(String name,int age,String sc){
this.name = name;
this.age = age;
this.school = sc;
}
public String talk1() {
/*不加这个的话,父类的talk1()方法不会被执行,因子类已经进行了方法的覆盖*/
return super.talk1()+"\n公司="+school;
}
}
运行结果:
姓名=五月天
年龄=32
公司=五迷五迷
三.类的多态
最重要的一个特性---多态
----3.1 多态的基本概念
重载的最终效果是调用同一个方法名称,却可以根据传入的参数不同的处理结果,这其实就是多态的一种体现。
代码案例:
package day09;
public class PolymorphismTest {
public static void main(String[] args) {
/*父类的对象通过子类进行的实例化,
* 所以在调用fun1(时,
* 调用的是子类的次方法*/
Person p = new Student();
p.fun1();
p.fun2();
}
}
class Person {
public void fun1() {
System.out.println("1.fun1()");
}
public void fun2() {
System.out.println("2.fun2()");
}
}
class Student extends Person{
//进行覆盖父类的fun1()方法
public void fun1() {
System.out.println("3.fun1()");
}
public void fun4() {
System.out.println("4.fun4()");
}
}
运行结果:
3.fun1()
2.fun2()
案例的原因是因为父类对象并非由其本身的类实例化,而是通过子类实例化
这就是所谓的对象的多态性,即子类实例化对象可以转换为父类实例化对象
星期二, 十一月 10, 2015 19:22:18 Java从入门到精通P182
----3.2 类的多态实例
在这里要讲解两个概念,予以重视。
3.2.1向上转型
向上转型
在上个例子中,父类对象通过子类对象去实例化,实际上就是对对象的向上转型。
向上转型是不需要进行强制类型转换的,但是向上转型会丢失精度。
向下转型
就是父类的对象可以转换为子类对象,但是需要注意的是,
这时则必须要进行强制的类型转换。
总结:
1.向上转型可以自动完成
2.向下转型必须进行强制类型转换
注意:
并非全部的父类对象都可以强制转换为子类对象。
代码案例:
package day09;
public class PolymorphismTest {
public static void main(String[] args) {
/*父类的对象通过子类进行的实例化,
* 所以在调用fun1(时,
* 调用的是子类的次方法*/
/*Person p = new Person();
将p向下转型:
* 父类用其本身类实例化自己的对象,
* 但它并不知道谁是自己的子类,
* 那肯定在转换时会出现错误。
* Exception in thread "main" java.lang.ClassCastException:
* day09.Person cannot be cast to day09.Student
at day09.PolymorphismTest.main(PolymorphismTest.java:11)
Student p2 = (Student)p;
*/
Person p = new Student();//p为person的子
Student p2 = (Student)p;
p2.fun1();
p2.fun2();
}
}
class Person {
public void fun1() {
System.out.println("1.fun1()");
}
public void fun2() {
System.out.println("2.fun2()");
}
}
class Student extends Person{
//进行覆盖父类的fun1()方法
public void fun1() {
System.out.println("3.fun1()");
}
public void fun3() {
System.out.println("4.fun3()");
}
}
运行结果:
3.fun1()
2.fun2()
问题总结:
父类用其本身类实例化自己的对象,但它并不知道谁是自己的子类,那肯定在转换时
会出现错误。
修改方法:
将实例化代码改为Person p = new Studengt();
这样就是由子类去实例化父类对象,
也就是说这个时候父类知道有这么一个子类,也就是相当于父亲知道自己有这么一个孩子。
所以下面再进行转换时就不会再有问题。
星期二, 十一月 10, 2015 20:08:41
相关推荐
day06【类与对象、封装、构造方法】 day07【Scanner类、Random类、ArrayList类】 day08【String类、static关键字、Arrays类、Math类】 day09【继承、super、this、抽象类】 day10【接口、多态】 day11【final、权限...
day06【类与对象、封装、构造方法】 day07【Scanner类、Random类、ArrayList类】 day08【String类、static关键字、Arrays类、Math类】 day09【继承、super、this、抽象类】 day10【接口、多态】 day11【final、权限...
day06【类与对象、封装、构造方法】 day07【Scanner类、Random类、ArrayList类】 day08【String类、static关键字、Arrays类、Math类】 day09【继承、super、this、抽象类】 day10【接口、多态】 day11【final、权限...
day06【类与对象、封装、构造方法】 day07【Scanner类、Random类、ArrayList类】 day08【String类、static关键字、Arrays类、Math类】 day09【继承、super、this、抽象类】 day10【接口、多态】 day11【final、权限...
day06【类与对象、封装、构造方法】 day07【Scanner类、Random类、ArrayList类】 day08【String类、static关键字、Arrays类、Math类】 day09【继承、super、this、抽象类】 day10【接口、多态】 day11【final、权限...
day06【类与对象、封装、构造方法】 day07【Scanner类、Random类、ArrayList类】 day08【String类、static关键字、Arrays类、Math类】 day09【继承、super、this、抽象类】 day10【接口、多态】 day11【final、权限...
day07_高级类特性1:封装、继承特性、方法重写与方法重载区别、this关键字 day08_高级类特性1:多态特性、4中访问权限修饰符、this与super区别、==与equals方法区别、instanceof操作符 day09_高级类特性1:toString...
定义一个 person类 要求有:属性 方法 封装 多态 继承
封装(类和私有变量) 继承 多态(python只能实现动态) issubclass(cls, 类或元组) 多继承 一个子类继承自两个或两个以上的父类 类的 __mro__ 属性绑定类的元组 用来记录方法的查找顺序 super 函数是按mro ...
A) 抽象类使类与类之间依旧具有父子联系,而接口一般只是定义了一种规范,并不使实现的接口之间具有父子关系。 B) 可以为抽象类定义对象,但是不能为接口定义对象。 C) 抽象类与接口的用法几乎都相同,具体用哪一个...
面向对象的三大特征:封装、继承、多态 其它关键字:this、super、abstract、interface、static、final、package、import 谈谈你对面向对象中类和对象的理解,并指出二者的关系? 类:抽象的、概念上的内容 对象:...
- **第二部分:Java面向对象核心逻辑:**`类和对象`、`封装`、`继承`、`多态`、`抽象`、`接口` - **第三部分:JavaSE核心高级应用:**`集合`、`I/O`、`多线程`、`网络编程`、`反射机制`、 - **第四部分:Java新特性...
Encapsulation[java] 封装 (hiding implementation details) Exception [java] 例外; 异常 [ik'sepʃәn] entry n.登录项, 输入项, 条目['entri] enum (关键字) execute vt.执行 ['eksikju:t] exhibit v.显示, ...