一、面向对象的特征一:封装与隐藏
需要对属性进行有条件限制,所有必须要用方法来设置返回,也就是说,把属性变成私有的,然后通过get、set方法来使用属性,限制属性额外附加的条件:比如输入的时候,字符大小不包含什么,直接使用就不可以
快捷键 Alt+Shift+S----->get、set方法生成 Alt+/---->查看构造器
1、问题引入
当我们创建一个类的对象以后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。这里,赋值操 作要受到属性的数据类型和存储范围的制约。除此之外,没有其他制约条件。但是,在实际问题中,我们往 往需要给属性赋值加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条 件的添加。(比如:set)。同时,我们需要避免用户再使用“对象.属性”的方式对属性进行赋值。则需要 将属性声明为私有的(private)
---->此时,针对于属性就体现了封装性
2、封装性的体现//get和set方法
我们将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)
拓展:封装性的体现:①如上②一个类中 有一个私有化方法,内部调用(不对外暴露的私有的方法)③单例模式…
public class PersonTest {
public static void main(String[] args) {
Person p=new Person();
p.setName("Tom");
String name=p.getName();
System.out.println(name);
}
}
class Person{
private String name;
//对属性的设置
public void setName(String name){
if(name=="Tom"){
this.name="Tom";
}else{
this.name="A";
}
}
//对属性的返回
public String getName(){
return this.name;
}
}
特别注意:封装性的体现需要权限修饰符来配合
1、Java规定的4种权限(从小到大排列):private、缺省(default不出现)、protected、public
2、private:类内部(出了一个类就不能使用)
缺省:类内部,同一个包(在同一个包下,创建某一个类的实例化,可以用缺省的属性、方法…)
protected:类内部、同一个包、不同包的子类(新创建一个包,包下创建的类继承了一个包的类,在新创的包下,可以调用protected的属性、方法)
public:类内部、同一个包、不同包的子类、同一个工程(通用)
3、4种权限可以用来修饰类的内部结构:属性、方法、构造器、内部类
4、具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
修饰类的话,只能使用:缺省、public
总结封装性:Java提供了4种权限修饰符来修饰内部类及类的内部结构,体现类及类的内部结构在被调用时的可见性大小
二、继承
public class PersonTest {
public static void main(String[] args) {
Student s = new Student("计算机科学与技术");
s.eat();
s.walk(10);
System.out.println("**************");
s.study();
Person p1 = new Person();
p1.eat();
}
}
public class Person {
String name;
int age;
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("吃饭");
}
public void walk(int distance){
System.out.println("走路,走的距离是:" + distance + "公里");
}
}
public class Student extends Person{
String major;
public Student(){
}
public Student(String major){
this.major = major;
}
public void study(){
System.out.println("学习。专业是:" + major);
}
//对父类中的eat()进行了重写
public void eat(){
System.out.println("学生应该多吃有营养的食物");
}
public void walk(int distance) {
System.out.println("重写的方法");
}
}
1、继承的好处
①减少了代码的冗余,提高了代码的复用性
②便于功能的扩展
③为之后多态性的使用,提供了前提
2、继承性的格式:
class A extends B{}
类A继承父类B
A:子类、派生类、subclass
B:父类、超类、基类、superclass
2.1体现:
一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性、方法
特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构
只是因为封装性的影响,使得子类不能直接调用父类的结构而已
2.2子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展
extends:延展、扩展
3、Java中关于继承性的一些规定
①一个父类可以被多个子类继承
②一个类只能有一个父类:java中类的单继承性
③子父类是相对的概念:多层继承
④子类直接继承的父类,称为:直接父类。间接继承的父类,称为:间接父类
⑤子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法
4、Object类
①如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.Object类
②所有的Java类(除java.lang.Object)都直接或间接的继承于java.lang.Object类
③意味着,所有的java类具有java.lang.Object类声明的功能
//继承是实线箭头
5、方法的重写(override/overwrite)
1、重写:
子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作
2、应用:
重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参数的方法时,实际执行的是子类重写父类的方法
3、重写的规定:
方法的声明:权限修饰符 返回值类型 方法名(形参列表)throws 异常的类型{
方法体
}
约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法
①子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
②子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符特殊情况:子类不能重写父类中声明为private权限的方法 ③返回值类型
父类被重写的方法的返回值是void,则子类重写的方法的返回值类型只能是void
父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A的子类
父类被重写的方法的返回值类型是基本数据类型(比如double),则子类重写的方法的返回值类型必须是 相同的 ④子类重写的方法**抛出的异常类型不大于父类被重写的方法抛出的异常类型(**具体放到异常处理时讲)子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)
//静态不能被覆盖
三、多态性
Person p2 = new Man();
p2.eat();
p2.walk();
在主函数中创建了一个子类的对象赋给父类,在调用方法的时候,实际上运行的(出结果的是)子类重写的方法,但是在编译的时候,编译器认为是父类中的方法。new的时候,子类所有的内容都被加载到堆空间,但是调用的时候,只能调用被重写的方法,其余的被隐藏
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.eat();
Man man = new Man();
man.eat();
man.age = 25;
man.earnMoney();
//*************************************************
System.out.println("*******************");
//对象的多态性:父类的引用指向子类的对象
Person p2 = new Man();
// Person p3 = new Woman();
//多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法 ---虚拟方法调用
p2.eat();
p2.walk();
// p2.earnMoney();
System.out.println(p2.id);//1001
}
}
public class Woman extends Person{
boolean isBeauty;
public void goShopping(){
System.out.println("女人喜欢购物");
}
public void eat(){
System.out.println("女人少吃,为了减肥");
}
public void walk(){
System.out.println("女人窈窕的走路");
}
}
public class Man extends Person{
boolean isSmoking;
int id = 1002;
public void earnMoney(){
System.out.println("男人负责挣钱养家");
}
public void eat(){
System.out.println("男人多吃肉,长肌肉");
}
public void walk(){
System.out.println("男人霸气的走路");
}
}
1、理解多态性:
可以理解为一个事物的多种形态
2、何为多态性:
对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
3、多态的使用:虚拟方法调用
有了对象的多态性以后,我们在编译器,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父 类的方法
总结:编译,看左边;运行,看右边
4、多态性的使用前提:
①类的继承关系②方法的重写
5、对象的多态性只适用于方法,不适用于属性(编译和运行都只看左边)
//多态性的使用举例一: 测试类父类 子类
public class AnimalTest {
public static void main(String[] args) {
AnimalTest test = new AnimalTest();
test.func(new Dog());
test.func(new Cat());
}
public void func(Animal animal){//Animal animal = new Dog();
animal.eat();
animal.shout();
if(animal instanceof Dog){
Dog d = (Dog)animal;
d.watchDoor();
}
}
}
class Animal{
public void eat(){
System.out.println("动物:进食");
}
public void shout(){
System.out.println("动物:叫");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
public void shout(){
System.out.println("汪!汪!汪!");
}
public void watchDoor(){
System.out.println("看门");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void shout(){
System.out.println("喵!喵!喵!");
}
}
//举例二:
class Order{
public void method(Object obj){
}
}
//举例三:
class Driver{
public void doData(Connection conn){//conn = new MySQlConnection(); / conn = new OracleConnection();
//规范的步骤去操作数据
// conn.method1();
// conn.method2();
// conn.method3();
}
}