面向对象特征--封装
封装含义: 1.包装,例如我们将一些征用的功能进行抽取,定义成一个方法 2.面向对象特征中的封装:隐藏,对类中的成员对外是否可见进行控制 使用权限修饰符控制成员对外可见性 封装案例1:将类中属性私有化 封装案例2:将某些方法私有化 java设计模式(模版,固定套路) 解决一类问题的固定方式 单例模式:单个实例,在系统中想让某个类只能创建一个对象
成员变量与局部变量 位置: 成员变量:在类中定义 局部变量:在方法中定义或者方法的参数 权限修饰不同 成员变量:可以使用权限修饰符(static) 局部变量:不可以使用权限修饰符 初始化不同: 成员变量: 非静态----在创建对象后,由构造方法初始化 静态----类加载时初始化 局部变量:声明后,使用前必须自己进行初始化 生命周期不同:(什么时候创建,什么时候销毁) 成员变量: 创建 销毁 非静态---创建对象 对象被垃圾回收 静态-----类加载时 类被卸载 局部变量: 创建 销毁 当方法被调用 当方法执行结束 在内存中位置不同: 成员变量: 非静态----与对象在堆空间存储 静态----与类信息在方法区中存储 局部变量: 与方法一样在栈空间中存储
public class Person {
/*
将成员变量设置为私有权限,在其他类不能直接访问
*/
private String name;
private int age;
public Person(){
}
//提供公共权限构造方法,外界通过构造方法对私有成员进行赋值
//但是需要使用成员变量的值时就不能获取到
public Person(String name, int age) {
if(name.length()>2&&name.length()<5){
this.name = name;
}
if(age>=0&&age<=150){
this.age = age;
}
}
public void setName(String name){
if(name.length()>2&&name.length()<5) {
this.name = name;
}
}
//给私有属性对外提供的公共全称的方法进行赋值与值的获取
public String getName(){
return this.name;
}
public void setAge(int age){
if(age>=0&&age<=150){
this.age = age;
}
}
public int getAge(){
return this.age;
}
public static void main(String[] args) {
Person person=new Person("aaaa",2222);
//在外部没有办法赋值时进行控制
Person p=new Person();
p.setName("张三丰");
p.setAge(123);
System.out.println(p.getName());
System.out.println(p.getAge());
}
}
}
public class MyWindow {
//定义静态变量,用来接收唯一的一个对象
static MyWindow m=null; //可以不写null
//将构造方法私有化,在其他类中无法使用构造方法,不能创建对象
private MyWindow(){
}
//对外提供了获取唯一对象的公共方法
public static MyWindow getMywindow(){
if(m==null){
m=new MyWindow();
}
return m;
}
public static void main(String[] args) {
System.out.println(MyWindow.getMywindow());
}
}
面向对象特征--继承
优点 减少代码冗余,提高代码复用性 更有利于功能的扩展(可以在类中维护各自的属性) 类与类产生了is-a关系
/*
java中如果一个类没有使用extends关键字显示的继承其他类
那么默认继承继承object类
object类是java体系中最顶级的类
所有类都直接或间接继承object类
*/
public class Animal {
private String name;
private int age;
public void eat(){
System.out.println("动物吃东西");
}
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;
}
}
/*
狗类继承动物类
extends 关键字
一个类不能继承多个类
只能继承一个类,但是可以多层继承
*/
public class Dog extends Animal {
public void lookhome(){
System.out.println("狗可以看家");
}
}
public class Test {
public static void main(String[] args) {
Dog dog=new Dog();
dog.setName("旺财");
dog.setAge(2);
dog.eat();
System.out.println(dog.getName()+":"+dog.getAge());
}
方法重载Overload:
1、同一个类中
2、方法名相同,参数列表不同(参数顺序、个数、类型)
3、方法返回值、访问权限符任意
方法重写Override:
1、有继承关系的子类中
2、方法名相同,参数列表相同(参数顺序、个数、类型),方法返回值相同
3、访问权限,访问权限需要大于等于父类的访问权限
注意:
构造方法,静态方法,成员变量不能重写
public class Animal {
private String name;
private int age;
public void eat(){
System.out.println("动物吃东西");
}
public void drink(){
System.out.println("动物喝水");
}
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 class Dog extends Animal {
/*
方法重写:
有时候,父类方法中的实现(父类方法中为完成功能所写的代码),不能满足子类的需要(与子类中的实现不同)
就可以将父类中的方法在子类中重写(在子类中对父类的某个方法重新定义)
这样子类重写的方法会覆盖掉父类的方法
注意:
构造方法,静态方法,成员变量不能重写
规则:
方法名相同,参数相同,返回值相同
子类重写的方法权限必须等于或大于父类方法的权限
子类重写方法结构应与父类方法结构一致
*/
// @Override注解标记,对方法进行标识,表示此方法是从父类中重写来的
// 在编译期间进行语法检测
/*@Override
public void eat() {
System.out.println("狗吃骨头");
}*/
@Override
public void eat(){
System.out.println("狗吃骨头");
}
public void drink(){
System.out.println("狗喝水");
}
public void lookhome(){
System.out.println("狗可以看家");
}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.drink();
}
}
super关键字
this:
this.属性 区别成员变量和局部变量
this.方法() 调用本类的某个方法(构造方法,成员方法) this表示当前对象
super
super.属性 表示父类对象中的成员变量 super.方法()表示父类对象中定义的方法 super() 表示调用父类构造方法 构造方法的第一行默认是super(); 可以写上,如果未写,在创建对象时会调用super(); super()只能在构造方法的第一行使用。
public class Animal {
private String name;
private int age;
public void eat(){
System.out.println("动物吃东西");
}
public void drink(){
System.out.println("动物喝水");
}
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 class Dog extends Animal{
/*
super
在子类中使用super关键字,访问父类定义的那部分成员.
super.成员变量
super.成员方法(常用)
*/
@Override
public void eat(){
System.out.println("狗吃骨头");
}
@Override
public void drink(){
System.out.println("狗喝水");
}
public void lookhome(){
//this.eat(); 调用当前对象的eat()
super.eat(); //在子类中调用父类定义的成员
System.out.println("狗可以看家");
}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
//dog.lookhome();
}
}
继承中的构造方法
子类继承父类时,不会继承父类的构造方法。只能通过“super(形参列表)” 的方式调用父类指定的构造方法。
规定super(形参列表),必须声明在构造器的首行。
如果在子类构造器的首行没有显示调用super(形参列表),则子类此构造器 默认调用super(),即调用父类中空参的构造器。
这么做是为了保证先对父类成员进行初始化。
开发中常见错误:
如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有空参
的构造器,则编译出错。
public class Animal {
private String name;
private int age;
public Animal(){
System.out.println("animal无参构造方法");
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("动物吃东西");
}
public void drink(){
System.out.println("动物喝水");
}
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 Dog(){
/*
子类构造方法中默认会调用父类无参构造方法
如果需要显示的使用super调用,必须放在构造方法的第一行
还可以调用父类中指定的构造方法
*/
System.out.println("Dog无参构造方法");
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat(){
System.out.println("狗吃骨头");
}
@Override
public void drink(){
System.out.println("狗喝水");
}
public void lookhome(){
System.out.println("狗可以看家");
}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
//new Dog("二哈",1);
}
}